Почему Elixir MapSet становится неупорядоченным после 32 элементов?

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]

Вотреализация в эликсире 1,3

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

Хотя порядок не имеет значения вMapSet, но все еще задаюсь вопросом, почемуMapSet становится неупорядоченным после 32 элементов?

Ответы на вопрос(1)

Решение Вопроса

Это не относится кMapSet, но то же самое происходит с нормальнымMap (MapSet использования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}

Это потому, что (скорее всего, в качестве оптимизации) Erlang хранит Карты размером доMAP_SMALL_MAP_LIMIT какотсортировано по ключу массив, Только после того, как размер больше, чемMAP_SMALL_MAP_LIMIT Эрланг переключается на хранение данных вHash Array Mapped Trie как структура данных, В не отладочном режиме Erlang,MAP_SMALL_MAP_LIMIT являетсяопределено как 32, поэтому все карты длиной до 32 должны печататься в отсортированном порядке. Обратите внимание, что это подробности реализации, насколько я знаю, и вы не должны полагаться на это поведение; они могут изменить значение константы в будущем или переключиться на совершенно другой алгоритм, если он более производительный.

 sbs15 июл. 2016 г., 06:05
Спасибо за объяснение!

Ваш ответ на вопрос