I know IO.iodata_to_binary performs well and is used in string building situations where performance matters.
However, I had a question if Enum.intersperse/2 and then IO.iodata_to_binary/1 Is better than just Enum.join/2 + string interpolation.
Here are my results.
Operating System: macOS
CPU Information: Intel(R) Core(TM) i5-9600K CPU @ 3.70GHz
Number of Available Cores: 6
Available memory: 32 GB
Elixir 1.14.3
Erlang 25.2.3
Benchmark suite executing with the following configuration:
warmup: 2 s
time: 5 s
memory time: 0 ns
reduction time: 0 ns
parallel: 1
inputs: Extra-Large, Large, Medium, Small
Estimated total run time: 1.40 min
Benchmarking intersperse + iodata_to_binary with input Extra-Large ...
Benchmarking intersperse + iodata_to_binary with input Large ...
Benchmarking intersperse + iodata_to_binary with input Medium ...
Benchmarking intersperse + iodata_to_binary with input Small ...
Benchmarking join + interpolate with input Extra-Large ...
Benchmarking join + interpolate with input Large ...
Benchmarking join + interpolate with input Medium ...
Benchmarking join + interpolate with input Small ...
Benchmarking join + join with input Extra-Large ...
Benchmarking join + join with input Large ...
Benchmarking join + join with input Medium ...
Benchmarking join + join with input Small ...
##### With input Extra-Large #####
Name                                     ips        average  deviation         median         99th %
join + interpolate                     0.163         6.14 s     ±0.00%         6.14 s         6.14 s
join + join                            0.134         7.44 s     ±0.00%         7.44 s         7.44 s
intersperse + iodata_to_binary        0.0812        12.31 s     ±0.00%        12.31 s        12.31 s
Comparison:
join + interpolate                     0.163
join + join                            0.134 - 1.21x slower +1.30 s
intersperse + iodata_to_binary        0.0812 - 2.00x slower +6.17 s
##### With input Large #####
Name                                     ips        average  deviation         median         99th %
intersperse + iodata_to_binary        368.98        2.71 ms   ±507.93%        2.27 ms        2.74 ms
join + interpolate                    338.50        2.95 ms    ±63.19%        2.84 ms        3.48 ms
join + join                           292.05        3.42 ms   ±455.98%        2.87 ms        3.43 ms
Comparison:
intersperse + iodata_to_binary        368.98
join + interpolate                    338.50 - 1.09x slower +0.24 ms
join + join                           292.05 - 1.26x slower +0.71 ms
##### With input Medium #####
Name                                     ips        average  deviation         median         99th %
join + interpolate                   10.81 K       92.52 μs  ±2567.59%       75.13 μs      117.02 μs
join + join                          10.52 K       95.06 μs  ±2873.40%       75.18 μs      120.45 μs
intersperse + iodata_to_binary       10.12 K       98.85 μs  ±2665.38%       81.06 μs      121.46 μs
Comparison:
join + interpolate                   10.81 K
join + join                          10.52 K - 1.03x slower +2.54 μs
intersperse + iodata_to_binary       10.12 K - 1.07x slower +6.32 μs
##### With input Small #####
Name                                     ips        average  deviation         median         99th %
join + interpolate                  496.88 K        2.01 μs  ±2641.54%        1.75 μs        3.00 μs
intersperse + iodata_to_binary      439.97 K        2.27 μs ±19344.53%        1.67 μs        2.21 μs
join + join                         388.93 K        2.57 μs ±17965.56%        1.82 μs        3.00 μs
Comparison:
join + interpolate                  496.88 K
intersperse + iodata_to_binary      439.97 K - 1.13x slower +0.26 μs
join + join                         388.93 K - 1.28x slower +0.56 μs
For small amounts of text they are pretty close. For extra-large, intersperse seems to hurt...