Skip to content

Instantly share code, notes, and snippets.

@brunoro
Last active December 18, 2015 12:58
Show Gist options
  • Save brunoro/5786164 to your computer and use it in GitHub Desktop.
Save brunoro/5786164 to your computer and use it in GitHub Desktop.
Pretty printer benchmark on deeply nested data structures
defmodule BenchmarkInspect do
def big_string do
s = trunc(:random.uniform * 400) + 1
String.duplicate "x", s
end
def rand_struct do
a = [
fn(x) -> { x, 1, 2 } end,
fn(x) -> { big_string, x, 2 } end,
fn(x) -> { 0, big_string, x } end,
fn(x) -> [ x, 1, 2 ] end,
fn(x) -> [ 0, x, big_string ] end,
fn(x) -> [ 0, 1, x ] end,
fn(x) -> [ a: x ] end,
fn(x) -> [ a: big_string, b: x ] end
]
i = trunc(:random.uniform * 8)
Enum.at! a, i
end
def build_size(0), do: "end"
def build_size(n), do: rand_struct().(build_size(n - 1, rand_struct))
def build_size(0, _), do: "end"
def build_size(n, s), do: s.(build_size(n - 1, rand_struct))
def time(f) do
t_before = :erlang.now()
return = f.()
t_after = :erlang.now()
{ return, :timer.now_diff(t_after, t_before) }
end
def mean_std(l) do
size = Enum.count l
sum = Enum.reduce l, 0, fn(n, a) -> a + n end
mean = sum / size
sq_diff = Enum.reduce l, 0, fn(n, a) -> :math.pow(mean - n, 2) + a end
std = :math.sqrt(sq_diff / size)
{ mean, std }
end
def two_decimal(n), do: :io_lib.format '~.2f', [n]
def do_it(dots, grain, runs) do
IO.puts "depth\tmean \tstd"
sizes = Enum.map (1..dots), fn(x) -> grain * x end
Enum.reduce sizes, "", fn(x, _) ->
s = build_size(x)
times = Enum.map (1..runs), fn(_) ->
{ _, elapsed } = time fn() -> Kernel.inspect s end
elapsed
end
{ mean, std } = mean_std times
IO.puts "#{x} \t#{two_decimal mean} \t#{two_decimal std}"
end
end
end
BenchmarkInspect.do_it(10, 50, 10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment