大型perl阵列减速

时间:2011-01-26 17:27:21

标签: arrays perl slowdown

我目前正在运行一个perl程序,我必须将100万行文本文件分解成块(每块大小在50到50,000行之间),然后运行一些计算等。现在,我将所有数据加载到array1中。我使用array2并使用它来提取我需要的数据块。然后我做我需要在阵列2上执行的操作,然后返回并抓住下一组。

示例数据

A,blah1,blah2

A,blah6,blah7

A,blah4,blah5

B,blah2,blah2

所以我会把前三个拿到阵列2中,对它们进行排序,然后继续下一组。我的程序开始时效果非常好,但后来经历了严重的减速。

50K需要50秒,100k需要184秒,150k需要360秒,200k需要581秒,并且只会随着程序的继续而呈指数级下降(500k线处为4500秒)

不,我不能为这个项目使用数据库,有什么建议吗?

my @Rows1=<FILE>;
my $temp = @Rows1;
for($k = 0; $k < $temp; $k++)
{
    my @temp2array = ();
    my $temp2count = 0;
    my $thisrow = $Rows1[$k];
    my @thisarray = split(',', $thisrow);
    my $currcode = $thisarray[0];
    my $flag123 = 0;
    $temp2array[$temp2count] = $thisrow;
    $temp2count++;
    while ($flag123 == 0)
    {
        $nextrow = $tuRows1[$k + 1];
        @nextarray = split(',', $nextrow);
        if ($currcode eq $nextarray[0])
        {
            $temp2array[$temp2count] = $nextrow;
            $k++;
            $temp2count++;
        }
        else
        {
            $flag123 = 1;
        }
    }
}

我编辑的代码更像是下面的答案,我有这些时间:

50k = 42,100k = 133,150k = 280,200k = 467,250k = 699,300k = 978,350k = 1313

它不完全保持线性,按照这种趋势,这个编程仍然需要14000+秒。我将调查代码的其他部分

2 个答案:

答案 0 :(得分:2)

将整个大文件加载到内存中会降低速度,因为操作系统需要开始交换虚拟内存页面。在这种情况下,最好只处理您需要的文件部分。

在您的情况下,您似乎在第一个字段中处理具有相同值的行,因此您可以执行以下操作:

my @lines = ();
my $current_key = '';

while (<FILE>) {
    my ($key) = split /,/;     # get first column
    if ($key ne $current_key) {
        # new key. Process all the lines from the previous key.
        if (@lines > 0) {
            process(@lines);
        }
        @lines = ();
        $current_key = $key;
    }
    push @lines, $_
}
# don't forget the lines from the last key
if (@lines > 0) {
    process(@lines);
}

这样,你只需要在内存中存储足够的行来组成一个组。

(我假设输入数据是按键排序或组织的。如果不是这样,你可以在文件中进行多次传递:第一次传递以查看需要处理的键,以及后续传递收集与每个密钥相关的行。)

答案 1 :(得分:0)

运行您显示的代码是否会减速?如果没有,问题在于实际处理每个@ temp2array块的代码,可能还有一些变量仍然从以前的块中遗留了数据。