2016-07-15 1 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] 

다음은 순서가 MapSet에 문제가되지 않는다하더라도엘릭서의 MapSet이 32 개 요소 뒤에 정렬되지 않은 이유는 무엇입니까?

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 

비약 1.3에서 implementation이다, 그러나 MapSet 32 개 요소 후 정렬되지 않은됩니다 왜 아직도 궁금해?

답변

11

이것은 MapSet에 국한되지이지만, 같은 일이 (MapSet는 후드 Map 사용) Map 정상으로 발생합니다

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} 

이 때문에 (최적화 등 대부분)입니다 얼랑 저장 크기의지도 최대 MAP_SMALL_MAP_LIMIT까지 sorted by keyarray. 크기가 MAP_SMALL_MAP_LIMIT보다 큰 경우에만 Erlang이 데이터를 Hash Array Mapped Trie like data structure에 저장하는 것으로 전환합니다. Erlang이 아닌 디버그 모드에서 MAP_SMALL_MAP_LIMITdefined to be 32이므로 길이가 32 인 모든 맵은 정렬 된 순서로 인쇄해야합니다. 이것이 내가 아는 한 구현 세부 사항이므로이 동작에 의존해서는 안됩니다. 미래의 상수 값을 변경하거나 더 많은 성능을 가진다면 완전히 다른 알고리즘으로 전환 할 수 있습니다.

+0

설명해 주셔서 감사합니다. – sbs

관련 문제