Performance Perl中unpack与join结合的性能

Performance Perl中unpack与join结合的性能,performance,perl,join,unpack,Performance,Perl,Join,Unpack,我有一个用Perl编写的解析器,它解析固定长度记录的文件。记录的一部分由几个字符串(也是固定长度)组成,仅由数字组成。字符串中的每个字符都编码为数字,而不是ASCII字符。也就是说,如果我有字符串12345,它的编码是01 02 03 04 05(而不是31 32 33 34 35) 我用unpack解析记录,这个特定的部分被解包为@array=unpack“C44”,$s。然后我用简单的连接恢复所需的字符串,比如$m=join(“,@array) 我想知道这是否是解码的最佳方式。文件相当大,有

我有一个用Perl编写的解析器,它解析固定长度记录的文件。记录的一部分由几个字符串(也是固定长度)组成,仅由数字组成。字符串中的每个字符都编码为数字,而不是ASCII字符。也就是说,如果我有字符串12345,它的编码是01 02 03 04 05(而不是31 32 33 34 35)

我用unpack解析记录,这个特定的部分被解包为
@array=unpack“C44”,$s
。然后我用简单的连接恢复所需的字符串,比如
$m=join(“,@array)

我想知道这是否是解码的最佳方式。文件相当大,有数百万条记录,显然,我试图寻找是否可以优化。分析器显示,大部分时间都花在解析记录上(即,读、写和其他内容都不是问题),而解析这些连接占用了大部分时间。我记得从其他来源,加入是相当有效的运作。如果有可能加快代码速度,或者它已经是最优的,有什么想法吗?也许可以以某种巧妙的方式避免这种中间数组,例如,使用pack/unpack组合

编辑:代码示例

我尝试优化的代码如下所示:

    while (read(READ, $buf, $rec_l) == $rec_l) {
        my @s = unpack "A24 C44 H8", $buf;
        my $msisdn = substr $s[0], 0, 11;
        my $address = join("", @s[4..14]);
        my $imsi = join("", @s[25..39]);
        my $ts = localtime(hex($s[45]));
    }

在Perl中,速度越快,可读性越差:-)


我不相信这个改变会加速你的代码。一切都取决于调用join函数读取整个文件的频率。如果你是分块工作,试着增加它们的大小。如果要在解包和加入此数组之间执行某些操作,请尝试使用映射操作将它们对齐。如果您发布源代码,那么就更容易识别瓶颈。

我是一个打包/解包的noob,但是通过如下更改示例代码来跳过连接怎么样:

my $m = unpack "H*", $s ;
快速测试:

#!/usr/bin/perl

use strict ;
use Test::More tests => 1 ;

is( unpack("H*", "\x12\x34\x56"),"123456");
未经测试(我会在不太忙的时候回来编辑),但如果我正确地完成了所有的数学运算,并且速度更快,这应该可以工作:

my ($msisdn, $address, $imsi, $ts) = 
    unpack "A11 x13 x3 a10 x10 a15 x5 N", $buf;
$address |= "0" x 10;
$imsi |= "0" x 15
$ts = localtime($ts);

除此之外,只需要小的修正就可以了。速度是我的两倍。查看这个解包,我想知道我是如何找到这些连接的:(@MariusM如果你告诉我更正的是什么,我很乐意编辑我的答案。
hex unpack'H8'
是一种非常迂回的解包方式。
unpack'N'
。修复。
my ($msisdn, $address, $imsi, $ts) = 
    unpack "A11 x13 x3 a10 x10 a15 x5 N", $buf;
$address |= "0" x 10;
$imsi |= "0" x 15
$ts = localtime($ts);