Skip to content

Instantly share code, notes, and snippets.

@joladev
Last active February 5, 2020 13:24
Show Gist options
  • Save joladev/9d72201983c4a75da1e1006fbabc9dc6 to your computer and use it in GitHub Desktop.
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`
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
)
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