Skip to content

Instantly share code, notes, and snippets.

@jarrodmoldrich
Created December 6, 2021 10:56
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 jarrodmoldrich/b518418a23e9271d83d187a1e3325c1b to your computer and use it in GitHub Desktop.
Save jarrodmoldrich/b518418a23e9271d83d187a1e3325c1b to your computer and use it in GitHub Desktop.
A benchmark of bit string reversal methods in Elixir
// Based on a discussion at:
// https://elixirforum.com/t/ingest-a-bitstring-from-least-significant-bit/44265/8
Mix.install([{:benchee, "~> 1.0"}])
use Bitwise
defmodule ReverseStringMap1 do
def lastbit(bitstring) do
size = bit_size(bitstring) - 1
<<_head :: size(size), bit :: 1 >> = bitstring
bit
end
def reverse_string_map(bitstring, so_far \\ [])
def reverse_string_map(<<>>, so_far), do: Enum.reverse(so_far)
def reverse_string_map(bitstring, so_far) do
headsize = bit_size(bitstring) - 1
<<head :: size(headsize), bit :: 1 >> = bitstring
reverse_string_map(<<head::size(headsize)>>, [bit | so_far])
end
end
defmodule ReverseStringMap2 do
def reverse_string_map(s), do: reverse_string_map(s, [], bit_size(s) - 1)
def reverse_string_map(<<>>, _, _), do: []
def reverse_string_map(<<bit::1, _::bits>>, so_far, 0), do: Enum.reverse([bit | so_far])
def reverse_string_map(s, so_far, prefix) do
<<_ :: size(prefix), bit::1, _::bits>> = s
reverse_string_map(s, [bit | so_far], prefix - 1)
end
end
defmodule ReverseBitString do
def reverse_bitstring(value) when is_bitstring(value) do
for << bit::1 <- value >>, reduce: {0, 0} do
{bits, write_idx} ->
{(bit <<< write_idx) ||| bits, write_idx + 1}
end
|> elem(0)
end
end
defmodule Simple do
def reverse_bitstring(value) when is_bitstring(value) do
(for << bit::1 <- value >>, into: [], do: bit)
|> Enum.reverse()
end
end
values =
for _i <- 1..100,
do: << (:rand.uniform(65535))::8 >>
Benchee.run(
%{
"comprehension and reverse" => fn ->
for value <- values,
do: Simple.reverse_bitstring(value)
end,
"function style" => fn ->
for value <- values,
do: ReverseStringMap1.reverse_string_map(value)
end,
"comprehension w/ reduce + bitwise operations" => fn ->
for value <- values,
do: ReverseBitString.reverse_bitstring(value)
end,
"function style 2" => fn ->
for value <- values,
do: ReverseStringMap2.reverse_string_map(value)
end
}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment