what set elixir

what - elixir map set



¿Por qué el MapSet de Elixir se desordena después de 32 elementos? (1)

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]

Aquí está la implementación en Elixir 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

A pesar de que el orden no importa en un MapSet , pero todavía se pregunta por qué un MapSet se desordena después de 32 elementos?


Esto no es específico de MapSet , pero lo mismo sucede con Map normal ( MapSet usa Map debajo del capó):

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}

Esto se debe a que (probablemente como una optimización) Erlang almacena Mapas de tamaño hasta MAP_SMALL_MAP_LIMIT como ordenados por matriz de claves . Solo después de que el tamaño sea mayor que MAP_SMALL_MAP_LIMIT Erlang cambia a almacenar los datos en una estructura de datos similar a la matriz Hash Array . En el modo sin depuración Erlang, MAP_SMALL_MAP_LIMIT se define como 32 , por lo que todos los mapas con una longitud de hasta 32 deben imprimirse en orden ordenado. Tenga en cuenta que esto es un detalle de implementación, que yo sepa, y no debe confiar en este comportamiento; pueden cambiar el valor de la constante en el futuro o cambiar a un algoritmo completamente diferente si es más eficiente.