1

この perl スクリプトを最適化する方法についての提案を探しています。

ファイルのマイナーな再フォーマットを行うためのこのスクリプトがあります。スクリプトは次のことを行います。

  1. 「|」を読み取ります STDIN の区切りファイル
  2. 末尾の空白を削除し、
  3. 「NULL」テキスト文字列を削除します
  4. 日付を含む列を「YYYY-MM-DD hh:mm」日付形式から「YYYYMMDD」形式に変換します。
  5. STDOUT に出力し、NULL の場合にデータの最後の列が失われないようにするためにクルージを実行します。列の数は、各行で同じである必要があります。

サンプル入力:

.091590.S           |CHF|SWX|2011-05-23 00:00|                   77.25|                    NULL|                    NULL|      78.620000000000005|                NULL
.091590.S           |CHF|SWX|2011-05-24 00:00|      77.599999999999994|                    NULL|                    NULL|                   77.25|                NULL
.091590.S           |CHF|SWX|2011-05-25 00:00|      77.760000000000005|                    NULL|                    NULL|      77.599999999999994|                NULL
.091590.S           |CHF|SWX|2011-05-26 00:00|      77.430000000000007|                    NULL|                    NULL|      77.760000000000005|                NULL
.091590.S           |CHF|SWX|2011-05-27 00:00|      77.909999999999997|                    NULL|                    NULL|      77.430000000000007|                NULL
.091590.S           |CHF|SWX|2011-05-30 00:00|      78.060000000000002|                    NULL|                    NULL|      77.909999999999997|                3506

FormattingScript.pl [列]

[col] は、単一の数値またはコンマで区切られた数値のリストです。この入力により、日付変換が必要な列が決まります。

@updcol = split(',',@ARGV[0]);

while (<STDIN>)
{
      s/.$/|DATAEND/g; ## USING THIS TO KEEP FROM TRUNCATING NULL LAST COLUMN
      s/^\s*//g;
      s/\s*$//g;
      s/\s*\|/\|/g;
      s/\|\s*/\|/g;
      s/\|NULL\|/\|\|/g;
      s/\|NULL\s*$/\|/g;
      s/\|NULL\s*/\|/g;
      s/\|NULL$/\|/g;
      @dataline = split('\|',$_);
if (@updcol[0] != 999) { ## REFORMAT DATES IF PARAM IS NOT 999
        foreach my $col (@updcol) {
        $dataline[$col]=substr($dataline[$col],0,4).substr($dataline[$col],5,2).substr($dataline[$col],8,2);
        }}
      $dataline[-1]="";
      $line=join('|',@dataline);
      print substr($line,0,-1)."\n";
}

exit 0;

サンプル出力:

.091590.S|CHF|SWX|2011-05-23 00:00|77.25|||78.620000000000005|
.091590.S|CHF|SWX|2011-05-24 00:00|77.599999999999994|||77.25|
.091590.S|CHF|SWX|2011-05-25 00:00|77.760000000000005|||77.599999999999994|
.091590.S|CHF|SWX|2011-05-26 00:00|77.430000000000007|||77.760000000000005|
.091590.S|CHF|SWX|2011-05-27 00:00|77.909999999999997|||77.430000000000007|
.091590.S|CHF|SWX|2011-05-30 00:00|78.060000000000002|||77.909999999999997|3506
4

2 に答える 2

9

最適化はすべてマイクロになるため、Benchmark を取り出して、同じことを行うさまざまな方法のテストを開始する必要があります。

コードを最適化するよりも、コードをクリーンアップする方がメリットがあります。

my @date_cols = split(/,/, shift(@ARGV));

while (<>) {
   #chomp;  # Redundant.
   my @fields = split(/\|/, $_, -1);

   for (@fields) {
      s/^\s+//;
      s/\s+\z//;
      s/^NULL\z//;
   }

   for (@fields[@date_cols]) {
      s/^(....)-(..)-(..).*/$1$2$3/s;
   }

   print(join('|', @fields), "\n");
}
于 2012-07-24T21:37:29.627 に答える
2

Regexp::Assembleを使用して正規表現を最適化できる場合があります。これにより、複数の正規表現を実行するよりも高速に実行される可能性が高い 1 つの正規表現にすべての正規表現を組み合わせることができます。

于 2012-07-25T04:47:32.147 に答える