从DATA文件句柄读取

时间:2015-06-17 12:32:53

标签: performance perl

我的perl模块需要使用一个大约309,000行的查找表。

目前,将表加载到数组中的部分(粗略地)看起来像这样:

use strict;
use warnings;

# load all the data from below
my @ref_data; 
while (<DATA>) {
    push @ref_data, $_
}
close DATA;

__DATA__
00004f15ed000023f2
00005015fc000623ec
000051160a000b23e7
000052161d001523e2
0000531631002223de
0000541645002e23da
... etc ... 

我自己的实验表明,此while循环加载数据大约需要0.1秒。这大约是这样做的两倍:

use strict;
use warnings;

# load all the data from below
my @ref_data = <DATA>; 
close DATA;

__DATA__
00004f15ed000023f2
00005015fc000623ec
000051160a000b23e7
000052161d001523e2
0000531631002223de
0000541645002e23da
... etc ...

这两者都比仅仅qw(...)围绕所有数据行或编辑源以便一次加载一个项目快得多。

我可以猜测大约100毫秒的大部分时间是磁盘时间,但是while循环是初始化我的数组的最快方法,还是我们可以通过使用其他一些Perl构造来加快速度?

2 个答案:

答案 0 :(得分:3)

我针对三种方法做了一些基准测试。我使用外部文件进行阅读(而不是__DATA__)。该文件包含300万行您使用的确切数据。

这些方法正在啜饮文件,逐行读取文件,并使用Storable作为上面提到的Sobrique。每项任务都运行100次。以下是结果,显示一旦使用Storable存储,它比其他两个快得多(比直线快118%,比啜食快45%):

           Rate  by_line by_slurp by_store
by_line  1.08/s       --     -33%     -54%
by_slurp 1.62/s      50%       --     -31%
by_store 2.36/s     118%      45%       --

这是我使用的代码:

#!/usr/bin/perl

use warnings;
use strict;

use Benchmark qw(cmpthese timethese);
use Storable;

my $file = 'in.txt';

storeit();

cmpthese(100, {
    'by_line' => \&by_line,
    'by_slurp' => \&by_slurp,
    'by_store' => \&by_store,
});

sub by_line {

    open my $fh, '<', $file
      or die "Can't open $file: $!";

    my @ref_data;

    for my $line (<$fh>){
        push @ref_data, $line;
    }
}

sub by_slurp {

    open my $fh, '<', $file
      or die "Can't open $file: $!";

    my @ref_data = <$fh>;
}  

sub storeit {
    open my $fh, '<', $file
      or die "Can't open $file: $!";

    my @ref_data = <$fh>;
    close $fh;

    store \@ref_data, 'store.dat';
}

sub by_store{

    my @ref_data = retrieve('store.dat');
}

答案 1 :(得分:2)

DATA是一个嵌入到脚本中的特殊文件句柄。它与正常读取文件中的数据没有太大区别。我建议虽然使用300k线的内联数据可能不是接近它的理想方式。

你看过Storable了吗?您可能会发现可以storeretrieve数据结构 - 您可能需要保留文件以进行初始加载。

或者 - 您实际上是否需要在内存中保存所有参考数据?直接内存访问速度很快,但如果你不进行顺序密钥处理,你可能会发现按需查找数据库样式更好吗?

如果失败了 - 您可能还会发现拥有一个独立的“加载器”线程来异步处理您的文件也可能是一个选项,因为虽然它仍然需要时间加载到内存中,但您的程序可以继续进行数据处理正在加载。

但从根本上说 - 你正在从磁盘中连续读取大量数据。它总是受到磁盘速度的限制。更快的磁盘意味着更快的负载。解决方法是从磁盘移动到内存(如数据库)。