import birl import birl/duration.{Duration} import gleam/int import gleam/io import gleam/list import gleam/otp/task import gleam/string import query import tree pub fn main() { kv_bench() tree_bench() } fn kv_bench() { let ts = birl.now() let tree = tree.new() |> fill(0) let ts2 = birl.now() let Duration(ms) = birl.difference(ts2, ts) { "Set 1M key-value pairs in " <> string.inspect(ms / 10) <> " ms." } |> io.debug let tasks = tree |> setup_tasks() let ts = birl.now() tasks |> list.map(fn(task) { task |> task.await_forever() }) let ts2 = birl.now() let Duration(ms) = birl.difference(ts2, ts) { "Read 1M key-value pairs using 10 actors in " <> string.inspect(ms / 10) <> " ms." } |> io.debug } fn fill(tree, i) { case i { 1_000_000 -> tree _ -> { let assert Ok(tree) = tree |> query.set([".", int.to_string(i)], tree.Int(i)) tree |> fill(i + 1) } } } fn get_100k(tree, i) { case i { 100_000 -> Nil _ -> { let rint = int.random(1_000_000) let assert Ok(_) = tree |> query.get([".", rint |> int.to_string()], False) get_100k(tree, i + 1) } } } fn setup_tasks(tree) { list.range(0, 10) |> list.map(fn(_) { task.async(fn() { tree |> get_100k(0) }) }) } fn tree_bench() { let paths = list.range(0, 1_000_000) |> list.map(fn(n) { n |> path }) let ts = birl.now() let tree = tree.new() |> fill_tree(paths) let ts2 = birl.now() let Duration(ms) = birl.difference(ts2, ts) { "Set 1M nodes in " <> string.inspect(ms / 10) <> " ms." } |> io.debug let tasks = tree |> setup_nodes_tasks(paths) let ts = birl.now() tasks |> list.map(fn(task) { task |> task.await_forever() }) let ts2 = birl.now() let Duration(ms) = birl.difference(ts2, ts) { "Read 1M nodes using 10 actors in " <> string.inspect(ms / 10) <> " ms." } |> io.debug } fn fill_tree(tree, paths) { paths |> list.fold(tree, fn(tree, path) { let assert Ok(tree) = tree |> query.set(path, tree.String("foo")) tree }) } fn setup_nodes_tasks(tree, paths) { let paths = paths |> list.sized_chunk(100_000) list.range(0, 10) |> list.map2(paths, fn(_, path) { task.async(fn() { tree |> get_nodes(path) }) }) } fn get_nodes(tree, paths) { paths |> list.fold(tree, fn(tree, path) { let _ = tree |> query.get(path, True) tree }) } fn path(i: Int) { { i |> int.to_string() |> string.to_graphemes } |> list.reverse() }