1

我正在寻找有关如何优化此 perl 脚本的建议。

我有这个脚本可以对文件进行一些小的重新格式化。该脚本执行以下操作:

  1. 读一个“|” 来自 STDIN 的分隔文件
  2. 删除尾随空格,
  3. 删除“NULL”文本字符串
  4. 将带有日期的列从“YYYY-MM-DD hh:mm”日期格式转换为“YYYYMMDD”格式。
  5. 打印到 STDOUT 并执行 kluge 以防止在最后一列数据为 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]

其中 [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优化您的正则表达式。这将使您能够将所有正则表达式组合成一个正则表达式,该正则表达式的执行速度可能比运行多个正则表达式更快。

于 2012-07-25T04:47:32.147 回答