Last active
February 5, 2020 13:24
-
-
Save joladev/9d72201983c4a75da1e1006fbabc9dc6 to your computer and use it in GitHub Desktop.
A benchmark comparing building a string through repeated concatenation vs using an iolist and `Enum.reverse/1` + `:erlang.iolist_to_binary/1`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule IOList do | |
@base62_alphabet "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" |> String.graphemes() | |
def random_chars(n) do | |
Enum.take_random(@base62_alphabet, n) |> Enum.join() | |
end | |
def with_iolist(input), do: with_iolist(input, []) | |
def with_iolist("", acc), do: acc |> Enum.reverse() |> :erlang.iolist_to_binary() | |
def with_iolist(<<first::utf8, rest::binary>>, acc) do | |
with_iolist(rest, [first | acc]) | |
end | |
def without_iolist(input), do: without_iolist(input, "") | |
def without_iolist("", acc), do: acc | |
def without_iolist(<<first::utf8, rest::binary>>, acc) do | |
without_iolist(rest, acc <> <<first::utf8>>) | |
end | |
end | |
inputs = %{ | |
"small" => IOList.random_chars(1000), | |
"medium" => IOList.random_chars(10000), | |
} | |
Benchee.run( | |
%{ | |
"with iolist" => fn i -> IOList.with_iolist(i) end, | |
"without iolist" => fn i -> IOList.without_iolist(i) end, | |
}, | |
inputs: inputs | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Erlang/OTP 22 [erts-10.5.6] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] | |
Operating System: macOS | |
CPU Information: Intel(R) Core(TM) i7-8559U CPU @ 2.70GHz | |
Number of Available Cores: 8 | |
Available memory: 16 GB | |
Elixir 1.9.2 | |
Erlang 22.1.8 | |
Benchmark suite executing with the following configuration: | |
warmup: 2 s | |
time: 5 s | |
memory time: 0 ns | |
parallel: 1 | |
inputs: medium, small | |
Estimated total run time: 28 s | |
Benchmarking with iolist with input medium... | |
Benchmarking with iolist with input small... | |
Benchmarking without iolist with input medium... | |
Benchmarking without iolist with input small... | |
##### With input medium ##### | |
Name ips average deviation median 99th % | |
with iolist 880.24 K 1.14 μs ±1536.80% 0.99 μs 1.99 μs | |
without iolist 349.90 K 2.86 μs ±744.25% 1.99 μs 5.99 μs | |
Comparison: | |
with iolist 880.24 K | |
without iolist 349.90 K - 2.52x slower +1.72 μs | |
##### With input small ##### | |
Name ips average deviation median 99th % | |
with iolist 881.35 K 1.13 μs ±1539.25% 0.99 μs 1.99 μs | |
without iolist 351.61 K 2.84 μs ±793.97% 1.99 μs 5.99 μs | |
Comparison: | |
with iolist 881.35 K | |
without iolist 351.61 K - 2.51x slower +1.71 μs |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment