Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add make bench. #14

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ docs-update: git-check-uncommited docs-build
fi
git checkout -


.PHONY: bench
bench:
@dune exec -- ./bench/Bench_main.exe --format=json
89 changes: 89 additions & 0 deletions bench/Bench_main.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
open Bechamel
open Toolkit

let make_all n =
let open Streaming in
Staged.stage @@ fun () ->
Stream.(0 -- n)
|> Stream.map (fun x -> x + 1)
|> Stream.filter (fun x -> x mod 3 = 0)
|> Stream.take (n / 2)
|> Stream.flat_map (fun x -> Stream.(x -- (x + 30)))
|> Stream.fold ( + ) 0


let test =
Test.make_indexed ~name:"all" ~fmt:"%s %d"
~args:[ 10; 100; 1_000; 10_000; 100_000; 1_000_000 ]
make_all


let benchmark () =
let ols =
Analyze.ols ~bootstrap:0 ~r_square:true ~predictors:Measure.[| run |]
in
let instances =
Instance.[ minor_allocated; major_allocated; monotonic_clock ]
in
let cfg =
Benchmark.cfg ~limit:2000 ~quota:(Time.second 0.5) ~kde:(Some 1000) ()
in
let raw_results = Benchmark.all cfg instances test in
let results =
List.map (fun instance -> Analyze.all ols instance raw_results) instances
in
let results = Analyze.merge ols instances results in
(results, raw_results)


let output_current_bench () =
let results, _ = benchmark () in
let json : Yojson.Safe.t =
Current_bench_bechamel.json_of_ols_results results
in
Yojson.Safe.pretty_to_channel stdout json;
print_newline ()


let output_notty () =
List.iter
(fun v -> Bechamel_notty.Unit.add v (Measure.unit v))
Instance.[ minor_allocated; major_allocated; monotonic_clock ];

let img (window, results) =
Bechamel_notty.Multiple.image_of_ols_results ~rect:window
~predictor:Measure.run results
in

let open Notty_unix in
let window =
match winsize Unix.stdout with
| Some (w, h) -> { Bechamel_notty.w; h }
| None -> { Bechamel_notty.w = 80; h = 1 }
in
let results, _ = benchmark () in
img (window, results) |> eol |> output_image


let main format =
match format with
| `Json -> output_current_bench ()
| `Table -> output_notty ()


let () =
let open Cmdliner in
let format =
let doc = "Benchmark output format." in
Arg.(
required
& opt (some (enum [ ("json", `Json); ("table", `Table) ])) None
& info [ "format" ] ~doc)
in

let info =
let doc = "Run the main streaming benchmark." in
Term.info "streaming-bench-main" ~doc
in
let term = Term.(const main $ format) in
Term.exit @@ Term.eval (term, info)
52 changes: 52 additions & 0 deletions bench/Current_bench_bechamel.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
type 'a result = (string, 'a) Hashtbl.t

type 'a results = (string, 'a result) Hashtbl.t

let process_results results =
let metrics_by_test = Hashtbl.create 16 in
Hashtbl.iter
(fun metric_name result ->
Hashtbl.iter
(fun test_name ols ->
let metrics =
try Hashtbl.find metrics_by_test test_name
with Not_found -> Hashtbl.create 16
in
Hashtbl.add metrics metric_name ols;
Hashtbl.replace metrics_by_test test_name metrics)
result)
results;
metrics_by_test


let json_of_ols ols =
match Bechamel.Analyze.OLS.estimates ols with
| Some [ x ] -> `Float x
| Some estimates -> `List (List.map (fun x -> `Float x) estimates)
| None -> `List []


let json_of_ols_results ?name (results : Bechamel.Analyze.OLS.t results) :
Yojson.Safe.t =
let metrics_by_test = process_results results in
let results =
metrics_by_test |> Hashtbl.to_seq
|> Seq.map (fun (test_name, metrics) ->
let metrics =
metrics |> Hashtbl.to_seq
|> Seq.map (fun (metric_name, ols) ->
(metric_name, json_of_ols ols))
|> List.of_seq
|> fun bindings -> `Assoc bindings
in
`Assoc [ ("name", `String test_name); ("metrics", metrics) ])
|> List.of_seq
|> fun items -> `List items
in
let bindings = [ ("results", results) ] in
let bindings =
match name with
| Some name -> ("name", `String name) :: bindings
| None -> bindings
in
`Assoc bindings
5 changes: 5 additions & 0 deletions bench/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(executable
(public_name streaming-bench-main)
(package streaming-bench)
(name Bench_main)
(libraries cmdliner yojson streaming bechamel bechamel-notty notty.unix))
27 changes: 27 additions & 0 deletions streaming-bench.opam
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
opam-version: "2.0"

homepage: "http://github.com/odis-labs/streaming"
doc: "https://odis-labs.github.io/streaming"
bug-reports: "https://github.com/odis-labs/streaming/issues"
license: "ISC"

authors: [
"Rizo I <[email protected]>"
]
maintainer: "Rizo I <[email protected]>"
dev-repo: "git+https://github.com/odis-labs/streaming.git"

synopsis: "Benchmarks for streaming."
depends: [
"dune" {>= "2.0"}
"ocaml" {>= "4.08.0"}
"cmdliner"
"streaming"
"bechamel"
"bechamel-notty"
"yojson"
]

build: [
["dune" "build" "-p" name "-j" jobs "@install" "@doc" {with-doc}]
]