You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Perl的File::Map比File::Slurp性能差这么多?

问题:File::Map处理大文件时性能暴跌,是用法问题还是模块本身缺陷?

我原本想用mmap搜索多GB级文件,避免内存耗尽。但测试一个能完全放入内存的文件时,File::Slurp版本耗时不到一分钟,File::Map版本跑了数分钟还没完成,只能终止。

测试小文件后发现,File::Map的性能随文件增大持续下降(文件大小翻倍,耗时变为4倍),而File::Slurp性能相对稳定(文件大小翻倍,耗时也翻倍)。

是我对该模块用法有误,还是File::Map处理大文件时本就很慢?

for n in 1 4 16 32 64 128 256 512 4096; do
    seq $n | xargs -I@ seq 100000  > data
    ls -l data
    time perl -MFile::Slurp -e '
          $s = read_file("data");
          $re = qr/^(99999|12345|4325|11111|50000)$/m;
          while ($s =~ m/$re/g){ ++$matches }
          print $matches;
    '
    time perl -MFile::Map=:all -e '
          map_file $s, "data";
          advise $s, "sequential";
          $re = qr/^(99999|12345|4325|11111|50000)$/m;
          while ($s =~ m/$re/g){ ++$matches }
          print $matches;
    '
done
n文件大小匹配次数用户耗时(Slurp)用户耗时(Slurp)/n系统耗时(Slurp)系统耗时(Slurp)/n用户耗时(Map)用户耗时(Map)/n系统耗时(Map)系统耗时(Map)/n
158889550.0330.0330.0070.0070.0140.0140.0010.001
42355580200.0510.0130.0070.0020.0320.0080.0050.001
169422320800.1090.0070.0150.0010.1380.0090.0120.001
32188446401600.1840.0050.0240.0010.4000.0130.0210.001
64376892803200.3280.0050.0490.0012.6660.0424.3050.067
128753785606400.6290.0050.0790.00110.0140.07817.6380.138
25615075712012801.2200.0050.1620.00140.2370.15773.8290.288
51230151424025602.4230.0050.3230.001158.7290.310302.0410.590
409624121139202048019.4680.0052.4240.001????

按照@TLP的建议,不再手动从ls和time输出计算表格,以下是Perl Benchmark版本的测试结果(已省略警告输出),同样显示File::Slurp性能不受文件大小影响,而File::Map性能随文件增大下降:

#!/bin/bash

for n in 1 4 16 32 64 128 256 512; do
    seq $n | xargs -I@ seq 100000 > data$n
done

perl -MBenchmark=cmpthese -MFile::Slurp -MFile::Map=:all -e '
    @n = (1,4,16,32,64,128,256,512);

    sub test_slurp {
          my ($s,$re,$matches);
          $s = read_file($f);
          $re = qr/^(99999|12345|4325|11111|50000)$/m;
          while ($s =~ m/$re/g){ ++$matches }
    }
    sub test_map {
          my ($mm,$re,$matches);
          map_file $mm, $f;
          advise $mm, "sequential";
          $re = qr/^(99999|12345|4325|11111|50000)$/m;
          while ($mm =~ m/$re/g){ ++$matches }
    }

    for $n (@n) {
        $f = "data$n";
        cmpthese(-1, { "map($n)" => \&test_map, "slurp($n)" => \&test_slurp });
    }
'
速率    map(1) slurp(1)
map(1)   198次/秒      --      -1%
slurp(1) 200次/秒      1%       --
           速率    map(4) slurp(4)
map(4)   38.3次/秒     --     -20%
slurp(4) 48.1次/秒    26%       --
            速率     map(16) slurp(16)
map(16)   6.60次/秒      --      -48%
slurp(16) 12.6次/秒     91%        --
            速率     map(32) slurp(32)
map(32)   1.98次/秒      --      -62%
slurp(32) 5.17次/秒    161%        --
          耗时/迭代   map(64) slurp(64)
map(64)     7.93秒        --      -96%
slurp(64)  0.350秒     2166%        --
           耗时/迭代   map(128) slurp(128)
map(128)     31.6秒         --       -98%
slurp(128)  0.730秒      4233%         --
           耗时/迭代   map(256) slurp(256)
map(256)      129秒         --       -99%
slurp(256)   1.55秒      8244%         --
           耗时/迭代   map(512) slurp(512)
map(512)      521秒         --       -99%
slurp(512)   2.82秒     18372%         --

内容的提问来源于stack exchange,提问作者jhnc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 19:57:03