Skip to content

Commit

Permalink
Simplify stat benchmark
Browse files Browse the repository at this point in the history
Instead of creating thousands of fibers and having them fight over a
semaphore, limit the number of fibers created. Also, fill the files with
zero bytes instead of asking the OS for secure random data, since that's
slow and isn't useful for the test.

This also makes the traces easier to view.
  • Loading branch information
talex5 committed Feb 14, 2024
1 parent 250afff commit 2a087ce
Showing 1 changed file with 13 additions and 23 deletions.
36 changes: 13 additions & 23 deletions bench/bench_stat.ml
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,19 @@ module Bench_dir = struct
| File { name; size; perm } ->
Fmt.pf ppf "file %s (0o%o) %Lu" name perm size

let make random fs t =
let limit = Eio.Semaphore.make 32 in (* Prevent FD exhaustion *)
let rec aux fs = function
let make fs t =
let rec aux iter fs = function
| Dir { name; perm; children } ->
let dir = fs / name in
Eio.Semaphore.acquire limit;
Path.mkdir ~perm dir;
Eio.Semaphore.release limit;
Fiber.List.iter (aux dir) children
iter (aux List.iter dir) children
| File { name; size; perm } ->
Eio.Semaphore.acquire limit;
let buf = Cstruct.create (Int64.to_int size) in
Eio.Flow.read_exact random buf;
Path.with_open_out ~create:(`If_missing perm) (fs / name) (fun oc ->
Eio.Flow.write oc [ buf ]
);
Eio.Semaphore.release limit
)
in
aux fs t
aux Fiber.List.iter fs t
end

let with_tmp_dir ~fs prefix suffix fn =
Expand All @@ -66,30 +60,27 @@ let with_tmp_dir ~fs prefix suffix fn =
fn dir

let bench_stat root =
let limit = Eio.Semaphore.make 32 in (* Prevent FD exhaustion *)
let rec aux dir =
Eio.Semaphore.acquire limit;
let rec aux level dir =
let { Eio.File.Stat.kind; perm; size; _ } = Path.stat ~follow:false dir in
match kind with
| `Directory ->
let items = Path.read_dir dir in
Eio.Semaphore.release limit;
let children = items |> Fiber.List.map (fun f -> aux (dir / f)) in
let map = if level > 3 then List.map else Fiber.List.map ?max_fibers:None in
let children = items |> map (fun f -> aux (level + 1) (dir / f)) in
let name = Path.native_exn dir |> Filename.basename in
Bench_dir.Dir { name; perm; children }
| `Regular_file ->
Eio.Semaphore.release limit;
let name = Path.native_exn dir |> Filename.basename in
File { name; perm; size = Optint.Int63.to_int64 size }
| _ -> assert false
in
aux root
aux 1 root

let file name = Bench_dir.File { name; perm = 0o644; size = 128L }
let dir name children = Bench_dir.Dir { name; perm = 0o700; children }

let random_bench_dir ~n ~levels =
if levels < 0 then invalid_arg "Levels should be > 0";
if levels < 1 then invalid_arg "Levels should be >= 1";
let rec loop root = function
| 1 -> (
match root with
Expand All @@ -109,12 +100,12 @@ let random_bench_dir ~n ~levels =
in
loop (dir "root" []) levels

let run_bench ~n ~levels ~random ~root ~clock =
let run_bench ~n ~levels ~root ~clock =
let dir = random_bench_dir ~levels ~n |> Bench_dir.sort in
traceln "Going to create %i files and directories" (Bench_dir.size dir);
let create_time =
let t0 = Eio.Time.now clock in
Bench_dir.make random root dir;
Bench_dir.make root dir;
let t1 = Eio.Time.now clock in
t1 -. t0
in
Expand Down Expand Up @@ -154,7 +145,6 @@ let run_bench ~n ~levels ~random ~root ~clock =

let run env =
let fs = Eio.Stdenv.fs env in
let random = Eio.Stdenv.secure_random env in
let clock = Eio.Stdenv.clock env in
with_tmp_dir ~fs "eio-bench-" "-stat" @@ fun root ->
run_bench ~n:20 ~levels:4 ~root ~random ~clock
run_bench ~n:20 ~levels:4 ~root ~clock

0 comments on commit 2a087ce

Please sign in to comment.