Skip to content

Instantly share code, notes, and snippets.

@nickva
Last active May 9, 2023 04:08
Show Gist options
  • Save nickva/fff7e2cc50b5f66177b39865258d8c65 to your computer and use it in GitHub Desktop.
Save nickva/fff7e2cc50b5f66177b39865258d8c65 to your computer and use it in GitHub Desktop.
Silly benchmark reading a block in a loop and measuring the average across multiple runs
%> filebench:all("...data.../filebench.couch").
% * bsize: 65536 pread: 11 couch_file pread: 74 write: 465 couch_file append_bin: 477
% * bsize: 16384 pread: 8 couch_file pread: 49 write: 218 couch_file append_bin: 277
% * bsize: 4096 pread: 9 couch_file pread: 41 write: 197 couch_file append_bin: 236
% * bsize: 1024 pread: 11 couch_file pread: 37 write: 183 couch_file append_bin: 222
%
-module(filebench).
-export([
all/1,
couch_file_reads/1,
couch_file_reads/3,
couch_file_writes/3,
file_reads/1,
file_reads/3,
file_writes/3
]).
all(Path) ->
all(Path, 1 bsl 16).
all(_Path, Bs) when Bs < 1024 ->
ok;
all(Path, Bs) ->
PlainUsec = file_reads(Path, Bs, 50000),
CouchUsec = couch_file_reads(Path, Bs, 50000),
WritesUsec = file_writes(Path, Bs, 500),
CouchWritesUsec = couch_file_writes(Path, Bs, 500),
io:format(" * bsize: ~p pread: ~p couch_file pread: ~p write: ~p couch_file append_bin: ~p~n",
[Bs, PlainUsec, CouchUsec, WritesUsec, CouchWritesUsec]),
all(Path, Bs bsr 2).
couch_file_reads(Path) ->
couch_file_reads(Path, 1000, 100000).
couch_file_reads(Path, Size, Reads) ->
{ok, Fd} = couch_file:open(Path, [create, overwrite]),
ok = couch_file:truncate(Fd, 0),
Bin = crypto:strong_rand_bytes(Size),
{ok, Pos, _} = couch_file:append_binary(Fd, Bin),
couch_file:sync(Fd),
T0 = erlang:monotonic_time(microsecond),
do_couch_file_reads(Fd, Pos, Size, Reads),
T1 = erlang:monotonic_time(microsecond),
couch_file:close(Fd),
round((T1 - T0) / Reads).
couch_file_writes(Path, Size, Writes) ->
{ok, Fd} = couch_file:open(Path, [create, overwrite]),
ok = couch_file:truncate(Fd, 0),
T0 = erlang:monotonic_time(microsecond),
do_couch_file_writes(Fd, Size, Writes),
T1 = erlang:monotonic_time(microsecond),
ok = couch_file:truncate(Fd, 0),
couch_file:close(Fd),
round((T1 - T0) / Writes).
do_couch_file_reads(_, _, _, 0) ->
ok;
do_couch_file_reads(Fd, Pos, ExpectSize, N) ->
{ok, Bin} = couch_file:pread_binary(Fd, Pos),
Size = size(Bin),
case Size =:= ExpectSize of
true ->
ok;
false ->
error({invalid_couch_file_size_read, Size, ExpectSize, N})
end,
do_couch_file_reads(Fd, Pos, ExpectSize, N-1).
do_couch_file_writes(_, _, 0) ->
ok;
do_couch_file_writes(Fd, Size, N) ->
{ok, _, _} = couch_file:append_binary(Fd, crypto:strong_rand_bytes(Size)),
ok = couch_file:sync(Fd),
do_couch_file_writes(Fd, Size, N-1).
file_reads(Path) ->
file_reads(Path, 1000, 100000).
file_reads(Path, Size, Reads) ->
{ok, Fd} = file:open(Path, [read, write, append, raw, binary]),
ok = file:truncate(Fd),
Bin = crypto:strong_rand_bytes(Size),
ok = file:write(Fd, Bin),
ok = file:sync(Fd),
T0 = erlang:monotonic_time(microsecond),
do_file_reads(Fd, 0, Size, Reads),
T1 = erlang:monotonic_time(microsecond),
file:close(Fd),
round((T1 - T0) / Reads).
file_writes(Path, Size, Writes) ->
{ok, Fd} = file:open(Path, [read, write, append, raw, binary]),
ok = file:truncate(Fd),
T0 = erlang:monotonic_time(microsecond),
do_file_writes(Fd, Size, Writes),
T1 = erlang:monotonic_time(microsecond),
ok = file:truncate(Fd),
file:close(Fd),
round((T1 - T0) / Writes).
do_file_reads(_, _, _, 0) ->
ok;
do_file_reads(Fd, Pos, ExpectSize, N) ->
{ok, Bin} = file:pread(Fd, Pos, ExpectSize),
Size = size(Bin),
case Size =:= ExpectSize of
true ->
ok;
false ->
error({invalid_file_size_read, Size, ExpectSize, N})
end,
do_file_reads(Fd, Pos, ExpectSize, N-1).
do_file_writes(_, _, 0) ->
ok;
do_file_writes(Fd, Size, N) ->
ok = file:write(Fd, crypto:strong_rand_bytes(Size)),
ok = file:sync(Fd),
do_file_writes(Fd, Size, N-1).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment