mar*_*ton 5 optimization perl unpack fixed-width
我们有一个成熟的代码体,可以将文件中的数据加载到数据库中.有几种文件格式; 它们都是固定宽度的字段.
部分代码使用Perl unpack()函数将输入数据中的字段读入包变量.然后,业务逻辑能够以"人类可读"的方式引用这些字段.
在读取文件之前,从格式描述生成文件读取代码一次.
在草图形式中,生成的代码如下所示:
while ( <> ) {
# Start of generated code.
# Here we unpack 2 fields, real code does around 200.
( $FIELDS::transaction_date, $FIELDS::customer_id ) = unpack q{A8 A20};
# Some fields have leading space removed
# Generated code has one line like this per affected field.
$FIELDS::customer_id =~ s/^\s+//;
# End of generated code.
# Then we apply business logic to the data ...
if ( $FIELDS::transaction_date eq $today ) {
push @fields, q{something or other};
}
# Write to standard format for bulk load to the database.
print $fh join( '|', @fields ) . q{\n} or die;
}
Run Code Online (Sandbox Code Playgroud)
对代码进行分析后发现,大约35%的时间花在解包和前导空间条带上.剩余时间用于验证和转换数据,以及写入输出文件.
似乎业务逻辑的任何一部分都不占运行时间的1-2%.
问题是 - 我们能否以某种方式从拆包和空间剥离中获得更多的速度?优选地,不必重构所有引用FIELDS包变量的代码.
编辑:
如果它有所作为
$ perl -v
This is perl, v5.8.0 built for PA-RISC1.1
Run Code Online (Sandbox Code Playgroud)
我实际上一遍又一遍地处理这个问题.解包比substr好.
就剥离空间而言,你几乎搞砸了.正则表达式黑客攻击是"官方"的方式.你可以通过改进你的unpack语句来获得一些效率(假设没有数据超过4位数,为什么解压缩字段的完整12位?),但除此之外,解析只是一个皮塔饼
祝你的平面数据好运.令人沮丧的传统垃圾,我多么讨厌它.
是的。使用提取substr可能是最快的方法。那是:
$FIELDS::transaction_date = substr $_, 0, 8;\n$FIELDS::customer_id = substr $_, 8, 20;\nRun Code Online (Sandbox Code Playgroud)\n\n可能会更快。现在,如果我手写这段代码,我不会放弃unpack,但如果你正在生成代码,你不妨尝试一下并测量一下。
另请参阅Perl\xe2\x80\x99s unpack() 比 substr() 更快吗?
\n\n至于剥离前导空格,s/^\\s+//可能是最快的方法。
更新:如果无法运行基准测试,就很难说任何明确的事情。然而,怎么样:
\n\nmy $x = substr $_, 0, 8;\nRun Code Online (Sandbox Code Playgroud)\n\n对于不需要任何修剪的字段
\n\nmy ($y) = substr($_, 8, 20) =~ /\\A\\s+(.+?)\\s+\\z/;\nRun Code Online (Sandbox Code Playgroud)\n\n那些需要修剪?
\n| 归档时间: |
|
| 查看次数: |
758 次 |
| 最近记录: |