treevault/test/benchmark.gleam
Ivan Yuriev 866d2dc255 full implementation!
needs heavy testing and benchmarking
2024-12-12 03:32:23 +03:00

110 lines
2.4 KiB
Gleam

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()
}