2014-07-03 48 views
1

我已經讀過,迭代散列比通過數組快得多。從哈希中檢索值也快得多。爲什麼要用數組而不是散列?

而不是使用一個數組,爲什麼不只是使用散列,並給每個鍵一個對應於索引的值?如果項目需要按順序排列,則可以對其進行排序。

+3

如果他們需要按他們插入的順序怎麼辦? – RobEarl

+0

@RobEarl ..你的修辭評論實際上是一個答案 - 好吧,如果它有一些更多的細節,我會投票它:) –

+0

你試過[基準](http://perldoc.perl.org/Benchmark。 HTML)它自己?如果你這樣做了,你會發現遍歷一個數組實際上要比遍歷一個散列快得多。 – ThisSuitIsBlackNot

回答

10

從哈希檢索中,你可以直接鍵,而不是遍歷整個哈希(或數組,當你搜索獲取價值感快特定的字符串)。話雖如此,$hash{key}不快於$array[0],因爲沒有迭代發生。

陣列無法通過哈希值來代替,因爲他們有不同的特點,

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

我沒有想到推/流行 – user86895

+3

不知道什麼「適合循環」的意思。您可以像遍歷數組元素一樣輕鬆地循環散列元素。 – ikegami

+1

'$ hash {key}'比'$ array [0]'慢,但它們的比例相同。 – ikegami

1

我覺得這是一個很好的問題:它沒有那麼多高水平的「語言設計」查詢這麼多,因爲它是一個實現問題。它的措辭可以強調這一點 - 比如說,對於特定的技術或用例,使用哈希與數組。

哈希很好,但是你需要列表/數組(c.f. @RobEarl)。你可以使用tie(或像Tie::IxHashTie::Hash::Indexed模塊)來「保留」散列的順序,但我相信這些必須比常規散列慢,在某些情況下,你不能傳遞它們或複製他們以完全相同的方式。

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:

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; 

要使用的代碼,這個驚人的集羣任何桶中的物品數量都很小。

恰當的哈希系統可以在碰撞次數過高時適當調整大小。你不想經常這樣做,因爲這是一個訂單N操作。

相關問題