Perl优化建议书

时间:2012-07-24 21:21:23

标签: perl optimization

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

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

  1. 读取“|”来自STDIN的分隔文件
  2. 删除尾随空格
  3. 删除“NULL”文本字符串
  4. 将日期中的列转换为“YYYY-MM-DD hh:mm”日期格式的“YYYYMMDD”格式。
  5. 打印到STDOUT并执行一个kluge以防止在NULL为NULL时丢失最后一列数据。每行的#列需要相同。
  6. 示例输入:

    .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
    

2 个答案:

答案 0 :(得分: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");
}

答案 1 :(得分:2)

您可以使用Regexp::Assemble优化正则表达式。这将使您能够将所有正则表达式组合成一个可能比运行多个正则表达式更快执行的正则表达式。