diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1daf0513..07b53c6e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,8 +24,9 @@ jobs: opam pin add -n conduit-async-ssl.dev . opam pin add -n conduit-lwt-tls.dev . opam pin add -n conduit-lwt-ssl.dev . + opam pin add -n conduit-bench.dev . opam depext -y conduit conduit-tls conduit-lwt conduit-async conduit-mirage - opam install --deps-only -t conduit conduit-tls conduit-lwt conduit-lwt-tls conduit-lwt-ssl conduit-async conduit-async-tls conduit-async-ssl conduit-mirage + opam install --deps-only -t conduit conduit-tls conduit-lwt conduit-lwt-tls conduit-lwt-ssl conduit-async conduit-async-tls conduit-async-ssl conduit-mirage conduit-bench - name: Build run: opam exec -- dune build - name: Test diff --git a/Makefile b/Makefile index 2d83066e..673509cd 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: build clean test doc +.PHONY: build clean test doc bench build: dune build @@ -11,3 +11,6 @@ clean: doc: dune build @doc + +bench: + @dune exec -- ./bench/cost.exe --json \ No newline at end of file diff --git a/bench/cost.ml b/bench/cost.ml index be91e6ce..9e15fb25 100644 --- a/bench/cost.ml +++ b/bench/cost.ml @@ -99,7 +99,42 @@ let fn_fully_abstr flow = Benchmark.V (fun () -> Tuyau.send flow hello_world) let fn_abstr (Tuyau.Flow (flow, (module Flow))) = Benchmark.V (fun () -> Flow.send flow hello_world) -let run () = +type result = { + with_conduit : float; + with_conduit_r2 : float; + without_conduit : float; + without_conduit_r2 : float; +} +[@@deriving to_yojson] + +let print_json est0 est1 r0 r1 = + let with_conduit = est0.(0) in + let with_conduit_r2 = r0 in + let without_conduit = est1.(0) in + let without_conduit_r2 = r1 in + let res = + { with_conduit; with_conduit_r2; without_conduit; without_conduit_r2 } in + let fmt = stdout |> Format.formatter_of_out_channel in + let open Yojson.Safe in + let obj = + `Assoc + [ + ( "results", + `Assoc + [ + ("name", `String "benchmarks"); ("metrics", result_to_yojson res); + ] ); + ] in + pretty_print fmt obj + +let print_stdout est0 est1 r0 r1 = + Fmt.pr "with Conduit:\t\t%fns (r²: %f).\n%!" est0.(0) r0 ; + Fmt.pr "without Conduit:\t%fns (r²: %f).\n%!" est1.(0) r1 ; + if r0 >= 0.99 && r1 >= 0.99 + then Fmt.pr "Overhead:\t\t%fns.\n%!" (est0.(0) -. est1.(0)) + else Fmt.epr "Bad regression coefficients!\n%!" + +let run json = let open Rresult in Tuyau.connect Unix.stderr fake0 >>= fun flow -> Tuyau.send flow hello_world >>= fun _ -> @@ -111,17 +146,23 @@ let run () = Linear_algebra.ols (fun m -> m.(1)) [| (fun m -> m.(0)) |] samples1 ) with | Ok (estimate0, r0), Ok (estimate1, r1) -> - Fmt.pr "with Conduit:\t\t%fns (r²: %f).\n%!" estimate0.(0) r0 ; - Fmt.pr "without Conduit:\t%fns (r²: %f).\n%!" estimate1.(0) r1 ; - if r0 >= 0.99 && r1 >= 0.99 - then Fmt.pr "Overhead:\t\t%fns.\n%!" (estimate0.(0) -. estimate1.(0)) - else Fmt.epr "Bad regression coefficients!\n%!" ; + (match json with + | true -> print_json estimate0 estimate1 r0 r1 + | false -> print_stdout estimate0 estimate1 r0 r1) ; Ok () | Error err, _ -> Error err | _, Error err -> Error err -let () = - match run () with +open Cmdliner + +let json = Arg.(value & flag & info [ "j"; "json" ]) + +let main json = + match run json with | Ok v -> v | Error (`Msg err) -> Fmt.epr "%s: %s.\n%!" Sys.argv.(0) err | Error `Not_found -> assert false + +let cmd = (Term.(const main $ json), Term.info "run benchmarks") + +let () = Term.(exit @@ eval cmd) diff --git a/bench/dune b/bench/dune index 19246a85..fc7cb22e 100644 --- a/bench/dune +++ b/bench/dune @@ -1,6 +1,9 @@ (executable - (name cost) - (libraries conduit unix rresult fmt) + (public_name cost) + (package conduit-bench) + (preprocess + (pps ppx_deriving_yojson)) + (libraries conduit unix rresult fmt cmdliner yojson ppx_deriving_yojson) (foreign_stubs (language c) (names rdtsc))) diff --git a/conduit-bench.opam b/conduit-bench.opam new file mode 100644 index 00000000..03db43f3 --- /dev/null +++ b/conduit-bench.opam @@ -0,0 +1,33 @@ +opam-version: "2.0" +maintainer: "anil@recoil.org" +authors: [ + "Anil Madhavapeddy" + "Thomas Leonard" + "Thomas Gazagnaire" + "Rudi Grinberg" + "Romain Calascibetta" +] +license: "ISC" +tags: "org:mirage" +homepage: "https://github.com/mirage/ocaml-conduit" +doc: "https://mirage.github.io/ocaml-conduit/" +bug-reports: "https://github.com/mirage/ocaml-conduit/issues" +dev-repo: "git+https://github.com/mirage/ocaml-conduit.git" +synopsis: "Conduit benchmarking suite" + +build: [ + ["dune" "subst"] {pinned} + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name] {with-test} +] + +depends: [ + "ocaml" {>= "4.07.0"} + "dune" {>= "2.0.0"} + "cmdliner" + "conduit" + "fmt" + "ppx_deriving_yojson" + "rresult" + "yojson" +]