更有效地存储数组散列中的值

时间:2013-04-01 02:17:06

标签: arrays performance perl hash

我正在研究一个生成大型数组散列(HoAs)数据结构的脚本。我正在尝试优化我的脚本,因为目前它正在运行。

最近我从一个网站上读到,一种可以进一步提高脚本执行速度的方法是使用一个子程序来存储值,例如数组的哈希值。它说它对大型数据结构特别有用。

这是文章给出的例子。

sub build_hash{
    # takes 3 params: hashref, name, and value
    return if not $_[2];

    push(@{ $_[0]->{'names'} }, $_[1]);
    push(@{ $_[0]->{'value'} }, $_[2]);

    # return a reference to the hash (smaller than making copy)
    return $_[0];
}

文章称,调用此子程序来构建HoA比将值推送到子程序之外的数组哈希值快40%。据说子程序很快,因为它使用引用来构建数据结构。

我想通过建立自己的HoA来测试这个子程序。假设我想创建以下数组哈希。

%HoA = (
    'C1' =>  ['1', '3', '3', '3'],
    'C2' => ['3','2'],
    'C3' => ['1','3','3','4','5','5'],
    'C4'  => ['3','3','4'],
    'C5' => ['1'],
);

我如何实现build_hash来执行此操作?另外,我该如何调用这个子程序?

这就是我所拥有的,但它并不是很有用。

# let AoA be an array of arrays that contains the values I want to assign
# to each key in %HoA
my @AoA = (
            ['1', '3', '3', '3'],
            ['3','2'],
            ['1','3','3','4','5','5'],
            ['3','3','4'],
            ['1']
          );
my %HoA;
my $count = 1;

foreach my $ref (@AoA){
    build_hash(\%HoA, $ref, "C$count");
    $count++;
}

sub build_hash {
    # takes 3 params: hashref, arrayref, and key
    return if not $_[2];
    push(@{ $_[0]->{$_[1]} }, $_[2]);

    # return reference to HoA_ref (smaller than making copy)
    return $_[0];
 }

3 个答案:

答案 0 :(得分:6)

我很高兴你喜欢我的演讲,但是我觉得如果没有与之相关的演讲,幻灯片的重点就不会出现。我试图展示如何直接访问@_而不是将内容复制到局部变量中可以节省一些非常频繁调用的和其他最小子的时间。

构建HoA不太可能是程序的缓慢部分。我建议你在我的幻灯片中显示更改之前做我做的事情,即在你的程序上运行Devel :: NYTProf并查看时间的去向。然后你就会知道需要修复什么。

答案 1 :(得分:2)

my %HoA; $HoA{"C$_"} = $AoA[$_-1] for 1..@AoA;

my %HoA; @HoA{ map "C$_", 1..@AoA } = @AoA;

my %HoA = map { "C$_" => $AoA[$_-1] } 1..@AoA;

从最快到最慢(我认为)排序,但它们大致都快于另一个。

答案 2 :(得分:2)

那些那些幻灯片根本说不出来。 Perrin所展示的是一种减少子调用开销的方法,假设您需要完全具有子程序,因为调用子程序需要时间。通过在不需要的地方添加子程序,您不会更快地编写代码。