Perl有什么更好的:哈希引用数组或“平”哈希列表?

时间:2009-07-24 19:33:49

标签: perl data-structures

我无法确定哪种方法更多(1)惯用Perl,(2)高效,或(3)“清除”。

让我用代码解释一下。首先,我可以做到

sub something {
  ...
  $ref->{size}   = 10;
  $ref->{name}   = "Foo";
  $ref->{volume} = 100;
  push (@references, $ref);
  ...
  return @references;
}

或者,我可以做到

sub something {
  ...
  push (@names, "Foo");
  $sizes{Foo}   =  10;
  $volumes{Foo} = 100;
  ...
  return (\@names, \%sizes, \%volumes);
}

两者基本上都是一样的。重要的是,我需要数组,因为我需要保持顺序。

我知道,总有不止一种方法可以做某些事情,但是,你更喜欢这两种方式中的哪一种?

4 个答案:

答案 0 :(得分:10)

不要用something之类的无意义术语思考,而要用具体的方式思考和说明问题。在这种情况下,您似乎返回了具有namesizevolume属性的对象列表。当你这样想时,没有理由考虑第二种方法。

如果你遇到问题,你可以考虑稍后进行优化,但即使你这样做,你可能会从Memoize获得更多,而不是爆炸数据结构。

我建议的一个效率改进是从这个子程序中返回一个引用:

sub get_objects {
    my @ret;

    while ( 'some condition' ) {
        #  should I return this one?
        push @ret, {
            name => 'Foo',
            size => 10,
            volume => 100,
        };
    }

    return \@ret;
}

答案 1 :(得分:5)

我非常喜欢前者。它将一个“数据包”(数据,大小,名称,数量)保存在一起,使代码更具可读性。

答案 2 :(得分:2)

将您的相关数据保存在一起。创建大型并行数组的唯一原因是因为你被迫。

如果您担心速度和内存使用情况,可以使用常量数组索引来访问命名字段:

use constant { SIZE => 0, NAME => 1, VOLUME => 2, };

sub something {
  ...

  $ref->[SIZE]   = 10;
  $ref->[NAME]   = "Foo";
  $ref->[VOLUME] = 100;

  push @references, $ref;

  ...
  return @references;
}

我还添加了一些空格以使代码更易于阅读。

如果我有很多带有验证规则和/或深度数据结构的参数,我倾向于通过将关于数据的逻辑与数据联系起来来查看对象以简化我的代码。当然,OOP确定速度惩罚,但我很少看到这成为一个问题。

对于快速和脏的OOP,我使用Class :: Struct,它有许多缺陷。对于我需要进行类型检查的情况,我使用Moose或Mouse(当内存或启动速度是一个大问题时)。

答案 3 :(得分:0)

这两种方式可能对不同的问题有用。如果您总是要一起访问所有信息,请将它们保持在一起。例如,在您的情况下,您要跟踪网页的名称,标题和大小。你可能同时处理所有这三件事,所以把它们作为一组哈希引用保存在一起。

其他时候,您可能会将数据分解为您单独使用的不同内容,并希望独立于其他列进行查找。在这些情况下,单独的哈希可能是有意义的。