我已经读过,迭代哈希比通过数组迭代要快得多。从散列中检索值也要快得多。
为什么不使用散列并为每个键赋予一个与索引相对应的值,而不是使用数组?如果项目需要按顺序排列,则可以对它们进行排序。
答案 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::IxHash
或Tie::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阶操作。