1

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

示例数据

A,等等,等等

A,等等6,等等7

A,等等4,等等5

乙,废话2,废话2

所以我会把前三个放到数组 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

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

4

2 回答 2

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);
}

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

(我假设输入数据是按键排序或组织的。如果不是这种情况,您可以通过文件进行多次传递:第一次传递以查看您需要处理哪些密钥,随后传递以收集与每个键关联的行。)

于 2011-01-26T17:45:32.843 回答
0

仅运行您显示的代码是否会减慢速度?如果不是,则问题出在实际处理每个 @temp2array 块的代码中,可能某些变量仍具有先前块遗留的数据。

于 2011-01-26T18:19:36.297 回答