Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@tony612
Last active July 25, 2019 07:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tony612/d71bf1cdea7487f452ed17adc7b17f29 to your computer and use it in GitHub Desktop.
Save tony612/d71bf1cdea7487f452ed17adc7b17f29 to your computer and use it in GitHub Desktop.
Erlang binary parsing comparing
# For 0000 0001 0100 0000 1000 1000
# The result is 0b1 + 0b100_0000 + 0b1000 = 73
defmodule BinaryParseFast do
def parse(bin) do
parse(bin, 0)
end
# def parse(<<0::1, x::7, _::bits>>, acc), do: acc + x
# def parse(<<1::1, x::7, rest::bits>>, acc) do
# parse(rest, acc + x)
# end
# Make it complex on purpose to be consistent with the slow version
def parse(bin, acc) do
do_parse(bin, acc)
end
# A byte beginning with 0 means the end, but still need to add the last 7 bits
def do_parse(<<0::1, x::7, _::bits>>, acc), do: acc + x
# A byte beginning with 1 means there is more data needed to be processed.
# and we need to add the last bits
def do_parse(<<1::1, x::7, rest::bits>>, acc) do
parse(rest, acc + x)
end
def run(bin) do
start = System.monotonic_time(:millisecond)
for _ <- 1..10000 do
505001 = parse(bin)
end
finish = System.monotonic_time(:millisecond)
finish - start
end
end
bin =
1..100
|> Enum.map(fn i ->
<<1::1, i::7>>
end)
|> List.duplicate(100)
|> IO.iodata_to_binary()
|> Kernel.<>(<<0::1, 1::7>>)
duration = BinaryParseFast.run(bin)
IO.puts "Total: #{duration}ms"
# Total: 1997ms
defmodule BinaryParseSlow do
def parse(bin) do
parse(bin, 0)
end
def parse(bin, acc) do
case do_parse(bin) do
{:nofin, x, rest} ->
parse(rest, acc + x)
{:fin, x} ->
acc + x
end
end
def do_parse(<<0::1, x::7, _::bits>>) do
{:fin, x}
end
def do_parse(<<1::1, x::7, rest::bits>>) do
{:nofin, x, rest}
end
def run(bin) do
start = System.monotonic_time(:millisecond)
for _ <- 1..10000 do
505001 = parse(bin)
end
finish = System.monotonic_time(:millisecond)
finish - start
end
end
bin =
1..100
|> Enum.map(fn i ->
<<1::1, i::7>>
end)
|> List.duplicate(100)
|> IO.iodata_to_binary()
|> Kernel.<>(<<0::1, 1::7>>)
duration = BinaryParseSlow.run(bin)
IO.puts "Total: #{duration}ms"
# Total: 6580ms
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment