As reported in: What would you remove from Elixir? - #77 by OvermindDL1
Does anyone know what’s up? Elixir 1.7.4 broke my comprehension code when it worked fine in 1.6.6.
Here is the bulk of the linked post:
I have my own project that replaces for
with a macro comp
rehension. ^.^
Mine decorates what you pass in with types (or ‘Access’ if not otherwise known) so it can generate optimal code for the specific types being used, meaning it’s faster than for
. It’s in one of my playground library and I should probably pull it out into it’s own project as it is quite functional…
My fairly trivial benchmark:
defmodule Helpers do
use ExCore.Comprehension
# map * 2
def elixir_0(l) do
for\
x <- l,
do: x * 2
end
def ex_core_0(l) do
comp do
x <- list l
x * 2
end
end
# Into map value to value*2 after adding 1
def elixir_1(l) do
for\
x <- l,
y = x + 1,
into: %{},
do: {x, y * 2}
end
def ex_core_1(l) do
comp do
x <- list l
y = x + 1
{x, y * 2} -> %{} # line 35
end
end
end
inputs = %{
"List - 10000 - map*2" => {:lists.seq(0, 10000), &Helpers.elixir_0/1, &Helpers.ex_core_0/1},
"List - 10000 - into map +1 even *2" => {:lists.seq(0, 10000), &Helpers.elixir_1/1, &Helpers.ex_core_1/1},
}
actions = %{
"Elixir.for" => fn {input, elx, _core} -> elx.(input) end,
"ExCore.comp" => fn {input, _elx, core} -> core.(input) end,
}
Benchee.run actions, inputs: inputs, time: 5, warmup: 5, print: %{fast_warning: false}
And the results locally right now:
Operating System: Linux
CPU Information: Blah
Number of Available Cores: 6
Available memory: 16.430148 GB
Elixir 1.6.6
Erlang 21.1.1
Benchmark suite executing with the following configuration:
warmup: 5.00 s
time: 5.00 s
parallel: 1
inputs: List - 10000 - into map +1 even *2, List - 10000 - map*2
Estimated total run time: 40.00 s
Benchmarking with input List - 10000 - into map +1 even *2:
Benchmarking Elixir.for...
Benchmarking ExCore.comp...
Benchmarking with input List - 10000 - map*2:
Benchmarking Elixir.for...
Benchmarking ExCore.comp...
##### With input List - 10000 - into map +1 even *2 #####
Name ips average deviation median
ExCore.comp 370.81 2.70 ms ±2.76% 2.67 ms
Elixir.for 245.68 4.07 ms ±21.72% 3.90 ms
Comparison:
ExCore.comp 370.81
Elixir.for 245.68 - 1.51x slower
##### With input List - 10000 - map*2 #####
Name ips average deviation median
ExCore.comp 2.50 K 399.55 μs ±9.28% 405.00 μs
Elixir.for 1.92 K 521.94 μs ±7.26% 535.00 μs
Comparison:
ExCore.comp 2.50 K
Elixir.for 1.92 K - 1.31x slower
Interestingly it won’t run on Elixir 1.7.4, get a syntax error, @josevalim did something change in a backwards incompatible way with Elixir 1.7.4? o.O
╰─➤ mix bench comprehension 1 ↵
** (SyntaxError) bench/comprehension_bench.exs:35: unexpected operator ->. If you want to define multiple clauses, the first expression must use ->. Syntax error before: '->'
(elixir) lib/code.ex:767: Code.require_file/2
(mix) lib/mix/tasks/run.ex:146: Mix.Tasks.Run.run/5
(mix) lib/mix/tasks/run.ex:85: Mix.Tasks.Run.run/1
(elixir) lib/enum.ex:1314: Enum."-map/2-lists^map/1-0-"/2
(mix) lib/mix/task.ex:355: Mix.Task.run_alias/3
(mix) lib/mix/task.ex:279: Mix.Task.run/2
I notated line 35 as # line 35
in the above benchmark source. Feel free to clone git clone https://github.com/OvermindDL1/ex_core.git && mix deps.get && mix compile && mix bench comprehension