为什么要使用数组而不是哈希?

时间:2014-07-03 15:44:54

标签: arrays perl hash

我已经读过,迭代哈希比通过数组迭代要快得多。从散列中检索值也要快得多。

为什么不使用散列并为每个键赋予一个与索引相对应的值,而不是使用数组?如果项目需要按顺序排列,则可以对它们进行排序。

4 个答案:

答案 0 :(得分:10)

从某种意义上来说,从哈希中检索更快,你可以直接通过键获取值而不是遍历整个哈希(或者当你搜索特定字符串时的数组)。话虽如此,$hash{key}并不比$array[0]快,因为没有迭代发生。

数组不能被哈希替换,因为它们具有不同的功能,

                       arrays hashes
------------------------------------
ordered keys            x       -
push/pop                x       -
suitable for looping    x       -
named keys              -       x

答案 1 :(得分:4)

我不知道你在哪里读到哈希比数组更快。根据一些Perl参考工作(Mastering Algorithms with Perl),数组比哈希更快(跟this link更多信息)。

如果速度是你唯一的标准,你应该进行基准测试,看看哪种技术会更快。这取决于你将对数组/哈希做什么操作。

以下是一个包​​含更多信息的SO链接:Advantage of 'one dimensional' hash over array in Perl

答案 2 :(得分:1)

我认为这是一个很好的问题:它不是一个高级别的“语言设计”查询,而是一个实现问题。它可以用一种强调的方式措辞 - 比如使用哈希与数组进行特定技术或用例。

哈希很好但你需要列表/数组( c.f。 @RobEarl)。您可以使用tie(或Tie::IxHashTie::Hash::Indexed等模块)来“保留”哈希的顺序,但我相信这些必须更慢而不是常规哈希,在某些情况下,你不能传递它们或以完全相同的方式复制它们。

答案 3 :(得分:1)

此代码或多或少是散列的工作方式。它应该很好地解释为什么你想要使用数组而不是哈希。

package DIYHash;
use Digest::MD5;

sub new {
     my ($class, $buckets) = @_;

     my $self = bless [], $class;
     $#$self = $buckets || 32;

     return $self;
}

sub fetch {
    my ( $self, $key ) = @_;

    my $i  = $self->_get_bucket_index( $key );
    my $bo = $self->_find_key_in_bucket($key);

    return $self->[$i][$bo][1];
}

sub store {
    my ( $self, $key, $value ) = @_;

    my $i  = $self->_get_bucket_index( $key );
    my $bo = $self->_find_key_in_bucket($key);
    $self->[$i][$bo] = [$key, $value];

    return $value;
}

sub _find_key_in_bucket {
    my ($self, $key, $index) = @_;

    my $bucket = $self->[$index];

    my $i = undef; 
    for ( 0..$#$bucket ) {
         next unless $bucket->[$_][0] eq $key;
         $i = $_;
    }
    $i = @$bucket unless defined $i;

    return $i;
}


# This function needs to always return the same index for a given key.
# It can do anything as long as it always does that.
# I use the md5 hashing algorithm here.
sub _get_bucket_index {
    my ( $self, $key ) = @_;

    # Get a number from 0 to 1 - bucket count.
    my $index = unpack( "I", md5($key) ) % @$self;

    return $index;
}

1;

使用这个惊人的代码集:

my $hash = DIYHash->new(4);  #This hash has 4 buckets.
$hash->store(mouse => "I like cheese");
$hash->store(cat => "I like mouse");

say $hash->fetch('mouse');

哈希看起来像是恒定的时间,而不是命令N,因为对于给定的数据集,您选择了一些桶来保持任何桶中的项目数量非常小。

当碰撞次数过高时,适当的散列系统可以适当调整大小。您不希望经常这样做,因为它是一个N阶操作。