Last active
July 21, 2024 16:14
-
-
Save evadne/33805e13f1d84eb2e32f0d1e1a376899 to your computer and use it in GitHub Desktop.
Reversing Binaries in Elixir
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 Benchmarker do | |
def run(title, module, function, size \\ 1024, iterations \\ 100) do | |
times = for (_ <- 1 .. iterations) do | |
data = :crypto.strong_rand_bytes(size) | |
{duration, _value} = :timer.tc fn -> | |
apply(module, function, [data]) | |
end | |
duration | |
end | |
avg = Enum.sum(times) / iterations | |
min = Enum.reduce(times, &Kernel.min/2) | |
max = Enum.reduce(times, &Kernel.max/2) | |
IO.puts "#{title} avg #{avg}µs / min #{min}µs / max #{max}µs" | |
end | |
end | |
defmodule ListReverse do | |
# | |
# https://elixir-lang.slackarchive.io/general/page-100/ts-1504036208000433 | |
# | |
def reverse(binary) do | |
binary |> :binary.bin_to_list |> Enum.reverse |> :binary.list_to_bin | |
end | |
end | |
defmodule EncodeDecodeEndiannessReverse do | |
# | |
# https://elixir-lang.slackarchive.io/general/page-100/ts-1504039301000460 | |
# | |
def reverse(binary) do | |
binary |> :binary.decode_unsigned(:little) |> :binary.encode_unsigned(:big) | |
end | |
end | |
defmodule ElixirBinaryReverse do | |
# | |
# https://github.com/comboy/elixir-binary/blob/master/lib/binary.ex#L54 | |
# | |
def reverse(binary) when is_binary(binary), do: do_reverse(binary, <<>>) | |
defp do_reverse(<<>>, acc), do: acc | |
defp do_reverse(<< x :: binary-size(1), bin :: binary >>, acc), do: do_reverse(bin, x <> acc) | |
end | |
defmodule IOListReverse do | |
# | |
# https://elixir-lang.slackarchive.io/general/page-100/ts-1504040788000314 | |
# | |
def reverse(binary) when is_binary(binary), do: do_reverse(binary, []) | |
defp do_reverse(<<>>, iolist), do: iolist |> IO.iodata_to_binary | |
defp do_reverse(<<chunk::size(8), rest::binary>>, iolist), do: do_reverse(rest, [chunk|iolist]) | |
end | |
for (size <- 1 .. 512) do | |
binary_size = size * 1024 | |
IO.puts("#{binary_size}bytes") | |
Benchmarker.run("ListReverse", ListReverse, :reverse, binary_size) | |
Benchmarker.run("ElixirBinaryReverse", ElixirBinaryReverse, :reverse, binary_size) | |
Benchmarker.run("EncodeDecodeEndiannessReverse", EncodeDecodeEndiannessReverse, :reverse, binary_size) | |
Benchmarker.run("IOListReverse", IOListReverse, :reverse, binary_size) | |
IO.puts("\n") | |
end |
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
$ elixir -v | |
Erlang/OTP 20 [erts-9.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace] | |
Elixir 1.5.0 |
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
$ elixir reverse.exs | |
1024bytes | |
ListReverse avg 11.28µs / min 6µs / max 24µs | |
ElixirBinaryReverse avg 218.95µs / min 175µs / max 437µs | |
EncodeDecodeEndiannessReverse avg 2.59µs / min 1µs / max 34µs | |
IOListReverse avg 14.25µs / min 13µs / max 19µs | |
2048bytes | |
ListReverse avg 19.58µs / min 11µs / max 39µs | |
ElixirBinaryReverse avg 590.19µs / min 504µs / max 1291µs | |
EncodeDecodeEndiannessReverse avg 4.26µs / min 3µs / max 16µs | |
IOListReverse avg 32.24µs / min 25µs / max 35µs | |
3072bytes | |
ListReverse avg 28.98µs / min 16µs / max 97µs | |
ElixirBinaryReverse avg 849.68µs / min 626µs / max 1637µs | |
EncodeDecodeEndiannessReverse avg 6.58µs / min 5µs / max 31µs | |
IOListReverse avg 45.52µs / min 39µs / max 116µs | |
4096bytes | |
ListReverse avg 51.03µs / min 22µs / max 110µs | |
ElixirBinaryReverse avg 1191.76µs / min 838µs / max 2200µs | |
EncodeDecodeEndiannessReverse avg 7.67µs / min 6µs / max 11µs | |
IOListReverse avg 59.56µs / min 57µs / max 129µs | |
5120bytes | |
ListReverse avg 52.52µs / min 28µs / max 132µs | |
ElixirBinaryReverse avg 1316.38µs / min 1136µs / max 2112µs | |
EncodeDecodeEndiannessReverse avg 8.97µs / min 8µs / max 12µs | |
IOListReverse avg 79.74µs / min 76µs / max 135µs | |
6144bytes | |
ListReverse avg 68.01µs / min 33µs / max 220µs | |
ElixirBinaryReverse avg 1702.35µs / min 1398µs / max 2952µs | |
EncodeDecodeEndiannessReverse avg 13.05µs / min 9µs / max 48µs | |
IOListReverse avg 97.84µs / min 85µs / max 164µs | |
7168bytes | |
ListReverse avg 80.03µs / min 38µs / max 221µs | |
ElixirBinaryReverse avg 2242.42µs / min 1731µs / max 3868µs | |
EncodeDecodeEndiannessReverse avg 12.7µs / min 11µs / max 25µs | |
IOListReverse avg 123.21µs / min 116µs / max 364µs | |
8192bytes | |
ListReverse avg 76.89µs / min 44µs / max 222µs | |
ElixirBinaryReverse avg 2651.06µs / min 2126µs / max 4184µs | |
EncodeDecodeEndiannessReverse avg 17.62µs / min 13µs / max 38µs | |
IOListReverse avg 144.82µs / min 122µs / max 252µs | |
9216bytes | |
ListReverse avg 97.82µs / min 51µs / max 283µs | |
ElixirBinaryReverse avg 2737.13µs / min 2461µs / max 4310µs | |
EncodeDecodeEndiannessReverse avg 16.19µs / min 14µs / max 30µs | |
IOListReverse avg 135.76µs / min 110µs / max 252µs | |
10240bytes | |
ListReverse avg 102.36µs / min 56µs / max 250µs | |
ElixirBinaryReverse avg 3380.27µs / min 2902µs / max 7774µs | |
EncodeDecodeEndiannessReverse avg 17.71µs / min 16µs / max 34µs | |
IOListReverse avg 146.43µs / min 139µs / max 246µs | |
11264bytes | |
ListReverse avg 122.44µs / min 62µs / max 290µs | |
ElixirBinaryReverse avg 3571.39µs / min 3286µs / max 5754µs | |
EncodeDecodeEndiannessReverse avg 18.36µs / min 17µs / max 24µs | |
IOListReverse avg 155.46µs / min 143µs / max 357µs | |
12288bytes | |
ListReverse avg 138.09µs / min 67µs / max 363µs | |
ElixirBinaryReverse avg 4264.24µs / min 3724µs / max 10531µs | |
EncodeDecodeEndiannessReverse avg 19.64µs / min 18µs / max 24µs | |
IOListReverse avg 247.94µs / min 189µs / max 445µs | |
13312bytes | |
ListReverse avg 176.45µs / min 75µs / max 457µs | |
ElixirBinaryReverse avg 4813.14µs / min 4033µs / max 13187µs | |
EncodeDecodeEndiannessReverse avg 23.67µs / min 19µs / max 52µs | |
IOListReverse avg 211.47µs / min 182µs / max 465µs | |
14336bytes | |
ListReverse avg 182.89µs / min 83µs / max 343µs | |
ElixirBinaryReverse avg 5599.34µs / min 4651µs / max 17518µs | |
EncodeDecodeEndiannessReverse avg 24.22µs / min 22µs / max 62µs | |
IOListReverse avg 222.13µs / min 169µs / max 1614µs | |
15360bytes | |
ListReverse avg 170.61µs / min 87µs / max 466µs | |
ElixirBinaryReverse avg 5996.69µs / min 5175µs / max 14345µs | |
EncodeDecodeEndiannessReverse avg 25.45µs / min 23µs / max 47µs | |
IOListReverse avg 239.96µs / min 209µs / max 1718µs | |
16384bytes | |
ListReverse avg 211.94µs / min 93µs / max 833µs | |
ElixirBinaryReverse avg 6923.24µs / min 5704µs / max 23778µs | |
EncodeDecodeEndiannessReverse avg 27.35µs / min 25µs / max 40µs | |
IOListReverse avg 248.79µs / min 207µs / max 433µs | |
17408bytes | |
ListReverse avg 210.82µs / min 96µs / max 627µs | |
ElixirBinaryReverse avg 7291.71µs / min 6716µs / max 10133µs | |
EncodeDecodeEndiannessReverse avg 32.23µs / min 28µs / max 83µs | |
IOListReverse avg 266.58µs / min 233µs / max 1642µs | |
18432bytes | |
ListReverse avg 302.28µs / min 108µs / max 1998µs | |
ElixirBinaryReverse avg 8644.68µs / min 7164µs / max 29917µs | |
EncodeDecodeEndiannessReverse avg 31.64µs / min 28µs / max 96µs | |
IOListReverse avg 458.31µs / min 227µs / max 2061µs | |
19456bytes | |
ListReverse avg 289.93µs / min 111µs / max 669µs | |
ElixirBinaryReverse avg 8947.74µs / min 7843µs / max 24326µs | |
EncodeDecodeEndiannessReverse avg 31.39µs / min 29µs / max 56µs | |
IOListReverse avg 324.25µs / min 300µs / max 437µs | |
20480bytes | |
ListReverse avg 254.55µs / min 118µs / max 688µs | |
ElixirBinaryReverse avg 10266.29µs / min 8872µs / max 45452µs | |
EncodeDecodeEndiannessReverse avg 35.59µs / min 31µs / max 72µs | |
IOListReverse avg 359.5µs / min 287µs / max 1766µs | |
21504bytes | |
ListReverse avg 267.76µs / min 124µs / max 1668µs | |
ElixirBinaryReverse avg 10956.76µs / min 9127µs / max 46210µs | |
EncodeDecodeEndiannessReverse avg 37.58µs / min 35µs / max 61µs | |
IOListReverse avg 359.84µs / min 319µs / max 1778µs | |
22528bytes | |
ListReverse avg 264.76µs / min 129µs / max 1684µs | |
ElixirBinaryReverse avg 12571.07µs / min 10486µs / max 49007µs | |
EncodeDecodeEndiannessReverse avg 38.87µs / min 35µs / max 82µs | |
IOListReverse avg 369.2µs / min 328µs / max 697µs | |
23552bytes | |
ListReverse avg 349.16µs / min 138µs / max 855µs | |
ElixirBinaryReverse avg 13702.08µs / min 12025µs / max 16531µs | |
EncodeDecodeEndiannessReverse avg 42.88µs / min 37µs / max 117µs | |
IOListReverse avg 373.01µs / min 336µs / max 971µs | |
24576bytes | |
ListReverse avg 315.76µs / min 141µs / max 897µs | |
ElixirBinaryReverse avg 16896.68µs / min 12733µs / max 61839µs | |
EncodeDecodeEndiannessReverse avg 47.48µs / min 38µs / max 423µs | |
IOListReverse avg 383.29µs / min 345µs / max 642µs | |
25600bytes | |
ListReverse avg 288.13µs / min 146µs / max 468µs | |
ElixirBinaryReverse avg 16532.1µs / min 13953µs / max 70851µs | |
EncodeDecodeEndiannessReverse avg 46.55µs / min 40µs / max 91µs | |
IOListReverse avg 421.08µs / min 354µs / max 870µs | |
26624bytes | |
ListReverse avg 325.52µs / min 153µs / max 562µs | |
ElixirBinaryReverse avg 17389.98µs / min 15177µs / max 33669µs | |
EncodeDecodeEndiannessReverse avg 51.5µs / min 40µs / max 776µs | |
IOListReverse avg 424.08µs / min 363µs / max 1840µs | |
27648bytes | |
ListReverse avg 310.86µs / min 162µs / max 508µs | |
ElixirBinaryReverse avg 19089.23µs / min 16323µs / max 80723µs | |
EncodeDecodeEndiannessReverse avg 49.22µs / min 43µs / max 147µs | |
IOListReverse avg 418.83µs / min 372µs / max 1866µs | |
28672bytes | |
ListReverse avg 322.86µs / min 166µs / max 712µs | |
ElixirBinaryReverse avg 22164.03µs / min 17393µs / max 85063µs | |
EncodeDecodeEndiannessReverse avg 54.55µs / min 44µs / max 233µs | |
IOListReverse avg 479.14µs / min 372µs / max 1053µs | |
29696bytes | |
ListReverse avg 327.86µs / min 171µs / max 914µs | |
ElixirBinaryReverse avg 22002.56µs / min 18456µs / max 79229µs | |
EncodeDecodeEndiannessReverse avg 55.63µs / min 45µs / max 126µs | |
IOListReverse avg 683.27µs / min 364µs / max 939µs | |
30720bytes | |
ListReverse avg 534.5µs / min 184µs / max 1446µs | |
ElixirBinaryReverse avg 24820.67µs / min 19417µs / max 260384µs | |
EncodeDecodeEndiannessReverse avg 59.82µs / min 48µs / max 132µs | |
IOListReverse avg 654.54µs / min 498µs / max 2189µs | |
31744bytes | |
ListReverse avg 524.47µs / min 187µs / max 1046µs | |
ElixirBinaryReverse avg 32961.49µs / min 20424µs / max 245010µs | |
EncodeDecodeEndiannessReverse avg 63.59µs / min 50µs / max 695µs | |
IOListReverse avg 562.86µs / min 489µs / max 1020µs | |
32768bytes | |
ListReverse avg 406.65µs / min 189µs / max 1732µs | |
ElixirBinaryReverse avg 25483.54µs / min 22194µs / max 76336µs | |
EncodeDecodeEndiannessReverse avg 72.18µs / min 51µs / max 1659µs | |
IOListReverse avg 540.45µs / min 497µs / max 1105µs | |
33792bytes | |
ListReverse avg 374.52µs / min 200µs / max 995µs | |
ElixirBinaryReverse avg 28571.68µs / min 23927µs / max 80112µs | |
EncodeDecodeEndiannessReverse avg 63.19µs / min 54µs / max 132µs | |
IOListReverse avg 740.56µs / min 522µs / max 1495µs | |
34816bytes | |
ListReverse avg 700.01µs / min 224µs / max 1327µs | |
ElixirBinaryReverse avg 28789.39µs / min 23619µs / max 105229µs | |
EncodeDecodeEndiannessReverse avg 57.6µs / min 50µs / max 87µs | |
IOListReverse avg 580.15µs / min 515µs / max 1172µs | |
35840bytes | |
ListReverse avg 658.56µs / min 212µs / max 1262µs | |
ElixirBinaryReverse avg 30905.4µs / min 26413µs / max 104325µs | |
EncodeDecodeEndiannessReverse avg 62.24µs / min 56µs / max 106µs | |
IOListReverse avg 562.41µs / min 523µs / max 805µs | |
36864bytes | |
ListReverse avg 437.74µs / min 220µs / max 1221µs | |
ElixirBinaryReverse avg 31324.7µs / min 25800µs / max 98197µs | |
EncodeDecodeEndiannessReverse avg 67.02µs / min 57µs / max 165µs | |
IOListReverse avg 615.57µs / min 533µs / max 2188µs | |
37888bytes | |
ListReverse avg 426.62µs / min 224µs / max 1098µs | |
ElixirBinaryReverse avg 33581.56µs / min 27411µs / max 93293µs | |
EncodeDecodeEndiannessReverse avg 65.78µs / min 54µs / max 130µs | |
IOListReverse avg 587.98µs / min 557µs / max 1004µs | |
38912bytes | |
ListReverse avg 494.81µs / min 223µs / max 2816µs | |
ElixirBinaryReverse avg 33823.14µs / min 29014µs / max 105475µs | |
EncodeDecodeEndiannessReverse avg 63.89µs / min 56µs / max 105µs | |
IOListReverse avg 610.12µs / min 508µs / max 2061µs | |
39936bytes | |
ListReverse avg 481.33µs / min 231µs / max 1948µs | |
ElixirBinaryReverse avg 37381.01µs / min 30712µs / max 117811µs | |
EncodeDecodeEndiannessReverse avg 69.28µs / min 62µs / max 111µs | |
IOListReverse avg 661.55µs / min 560µs / max 2669µs | |
40960bytes | |
ListReverse avg 488.86µs / min 241µs / max 1118µs | |
ElixirBinaryReverse avg 37384.78µs / min 31563µs / max 124126µs | |
EncodeDecodeEndiannessReverse avg 73.65µs / min 66µs / max 155µs | |
IOListReverse avg 735.47µs / min 585µs / max 1620µs | |
41984bytes | |
ListReverse avg 532.21µs / min 252µs / max 1288µs | |
ElixirBinaryReverse avg 41592.44µs / min 34539µs / max 168248µs | |
EncodeDecodeEndiannessReverse avg 73.13µs / min 65µs / max 137µs | |
IOListReverse avg 662.48µs / min 577µs / max 1659µs | |
43008bytes | |
ListReverse avg 525.35µs / min 253µs / max 1400µs | |
ElixirBinaryReverse avg 42198.1µs / min 34590µs / max 133351µs | |
EncodeDecodeEndiannessReverse avg 76.82µs / min 67µs / max 133µs | |
IOListReverse avg 655.26µs / min 570µs / max 1225µs | |
44032bytes | |
ListReverse avg 560.14µs / min 247µs / max 1420µs | |
ElixirBinaryReverse avg 42445.36µs / min 37178µs / max 137053µs | |
EncodeDecodeEndiannessReverse avg 73.73µs / min 67µs / max 101µs | |
IOListReverse avg 634.36µs / min 579µs / max 1357µs | |
45056bytes | |
ListReverse avg 562.18µs / min 253µs / max 1256µs | |
ElixirBinaryReverse avg 45221.23µs / min 37172µs / max 137744µs | |
EncodeDecodeEndiannessReverse avg 78.58µs / min 72µs / max 128µs | |
IOListReverse avg 708.91µs / min 622µs / max 1986µs | |
46080bytes | |
ListReverse avg 548.07µs / min 274µs / max 1874µs | |
ElixirBinaryReverse avg 47539.79µs / min 39983µs / max 153474µs | |
EncodeDecodeEndiannessReverse avg 76.78µs / min 66µs / max 146µs | |
IOListReverse avg 711.16µs / min 614µs / max 1441µs | |
47104bytes | |
ListReverse avg 561.57µs / min 286µs / max 1326µs | |
ElixirBinaryReverse avg 48946.26µs / min 40526µs / max 160503µs | |
EncodeDecodeEndiannessReverse avg 81.16µs / min 73µs / max 138µs | |
IOListReverse avg 692.18µs / min 622µs / max 2143µs | |
48128bytes | |
ListReverse avg 854.93µs / min 292µs / max 1626µs | |
ElixirBinaryReverse avg 50468.47µs / min 42589µs / max 175154µs | |
EncodeDecodeEndiannessReverse avg 85.94µs / min 77µs / max 141µs | |
IOListReverse avg 1252.25µs / min 614µs / max 2311µs | |
49152bytes | |
ListReverse avg 950.32µs / min 299µs / max 1939µs | |
ElixirBinaryReverse avg 70767.18µs / min 47875µs / max 706703µs | |
EncodeDecodeEndiannessReverse avg 87.94µs / min 79µs / max 144µs | |
IOListReverse avg 1050.5µs / min 803µs / max 1585µs | |
… |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment