2016-07-15 48 views
8
iex> MapSet.new(1..32) |> Enum.to_list 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 
23, 24, 25, 26, 27, 28, 29, 30, 31, 32] 

iex> MapSet.new(1..33) |> Enum.to_list 
[11, 26, 15, 20, 17, 25, 13, 8, 7, 1, 32, 3, 6, 2, 33, 10, 9, 19, 14, 5, 18, 31, 
22, 29, 21, 27, 24, 30, 23, 28, 16, 4, 12] 

Emir burada bir MapSet bir önemi olmasa daElixir'in MapSet'i 32 elemandan sonra neden sırasız hale geliyor?

def new(enumerable) do 
    map = 
    enumerable 
    |> Enum.to_list 
    |> do_new([]) 

    %MapSet{map: map} 
end 

defp do_new([], acc) do 
    acc 
    |> :lists.reverse 
    |> :maps.from_list 
end 

defp do_new([item | rest], acc) do 
    do_new(rest, [{item, true} | acc]) 
end 

Elixir 1.3 içinde implementation, ama bir MapSet 32 eleman sonra sırasız hale niye hala merak?

cevap

11

Bu MapSet özgü değildir, ama aynı şey (MapSet başlık altında Map kullanır) Map normale ile gerçekleşir:

iex(1)> for i <- Enum.shuffle(1..32), into: %{}, do: {i, i} 
%{1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, 
    10 => 10, 11 => 11, 12 => 12, 13 => 13, 14 => 14, 15 => 15, 16 => 16, 
    17 => 17, 18 => 18, 19 => 19, 20 => 20, 21 => 21, 22 => 22, 23 => 23, 
    24 => 24, 25 => 25, 26 => 26, 27 => 27, 28 => 28, 29 => 29, 30 => 30, 
    31 => 31, 32 => 32} 
iex(2)> for i <- Enum.shuffle(1..33), into: %{}, do: {i, i} 
%{11 => 11, 26 => 26, 15 => 15, 20 => 20, 17 => 17, 25 => 25, 13 => 13, 8 => 8, 
    7 => 7, 1 => 1, 32 => 32, 3 => 3, 6 => 6, 2 => 2, 33 => 33, 10 => 10, 9 => 9, 
    19 => 19, 14 => 14, 5 => 5, 18 => 18, 31 => 31, 22 => 22, 29 => 29, 21 => 21, 
    27 => 27, 24 => 24, 30 => 30, 23 => 23, 28 => 28, 16 => 16, 4 => 4, 12 => 12} 

Bunun nedeni (bir optimizasyon olarak büyük olasılıkla) 'dir Erlang mağazalarında boyutta Haritalar sorted by keyarray olarak MAP_SMALL_MAP_LIMIT'a kadar. Sadece boyut MAP_SMALL_MAP_LIMIT'dan büyükse, Erlang, verileri bir Hash Array Mapped Trie like data structure içinde saklamak için geçer. Hata ayıklama modunda Erlang, MAP_SMALL_MAP_LIMIT, defined to be 32, bu nedenle 32'ye kadar uzunluktaki tüm haritalar, sıralanmış sırayla yazdırılmalıdır. Bunun bildiğim kadarıyla bir uygulama detayı olduğunu ve bu davranışa güvenmemelisiniz; Gelecekte sabitin değerini değiştirebilir veya daha performanslı ise tamamen farklı bir algoritmaya geçebilirler.

+0

Açıklama için teşekkürler! – sbs