Skip to content

Instantly share code, notes, and snippets.

@nickva
Created October 14, 2025 18:34
Show Gist options
  • Select an option

  • Save nickva/d43b7ffd9997cd251f4573e2be25abec to your computer and use it in GitHub Desktop.

Select an option

Save nickva/d43b7ffd9997cd251f4573e2be25abec to your computer and use it in GitHub Desktop.
RevId Parsing CouchDB Benchmark: decode_hex vs binary_to_integer(RevId, 16)
-module(bench_parse_revid).
-export([go/0]).
-define(REPEAT, 100).
go() ->
go([10, 100, 500, 1000, 2500]).
go([]) ->
ok;
go([N | Rest]) ->
io:format("* N: ~p~n", [N]),
Revs = [binary:encode_hex(crypto:strong_rand_bytes(16), lowercase) || _ <- lists:seq(1, N)],
Dt1 = erlang:convert_time_unit(revid1(Revs), native, microsecond),
Dt2 = erlang:convert_time_unit(revid2(Revs),native, microsecond),
Lists = [binary_to_list(B) || B <- Revs],
Dt3 = erlang:convert_time_unit(revid1_list(Lists),native, microsecond),
Dt4 = erlang:convert_time_unit(revid2_list(Lists),native, microsecond),
io:format("* b2i + <<_:128>> : ~p~n", [Dt1]),
io:format("* decode_hex : ~p (faster pct:~p)~n", [Dt2, round((Dt1-Dt2)/Dt1*100)]),
io:format("* l2i + <<_:128>> : ~p~n", [Dt3]),
io:format("* l2b + decode_hex : ~p (faster pct:~p)~n", [Dt4, round((Dt3-Dt4)/Dt3*100)]),
io:format("************~n~n", []),
go(Rest).
revid1(Revs) ->
T0 = erlang:monotonic_time(),
lists:foreach(fun(_) -> parse_revid1_int(Revs, []) end, lists:seq(1,?REPEAT)),
round((erlang:monotonic_time() - T0)/?REPEAT).
revid2(Revs) ->
T0 = erlang:monotonic_time(),
lists:foreach(fun(_) -> parse_revid2_int(Revs, []) end, lists:seq(1,?REPEAT)),
round((erlang:monotonic_time() - T0)/?REPEAT).
revid1_list(Revs) ->
T0 = erlang:monotonic_time(),
lists:foreach(fun(_) -> parse_revid1_list_int(Revs, []) end, lists:seq(1,?REPEAT)),
round((erlang:monotonic_time() - T0)/?REPEAT).
revid2_list(Revs) ->
T0 = erlang:monotonic_time(),
lists:foreach(fun(_) -> parse_revid2_list_int(Revs, []) end, lists:seq(1,?REPEAT)),
round((erlang:monotonic_time() - T0)/?REPEAT).
parse_revid1_int([], Acc) ->
Acc;
parse_revid1_int([RevId | Rest], Acc) ->
RevInt = binary_to_integer(RevId, 16),
parse_revid1_int(Rest, [<<RevInt:128>> | Acc]).
parse_revid2_int([], Acc) ->
Acc;
parse_revid2_int([RevId | Rest], Acc) ->
parse_revid2_int(Rest, [binary:decode_hex(RevId) | Acc]).
parse_revid1_list_int([], Acc) ->
Acc;
parse_revid1_list_int([RevId | Rest], Acc) ->
RevInt = list_to_integer(RevId, 16),
parse_revid1_list_int(Rest, [<<RevInt:128>> | Acc]).
parse_revid2_list_int([], Acc) ->
Acc;
parse_revid2_list_int([RevId | Rest], Acc) ->
parse_revid2_list_int(Rest, [binary:decode_hex(list_to_binary(RevId)) | Acc]).
@nickva
Copy link
Author

nickva commented Oct 14, 2025

Erlang 26, Intel(R) Xeon(R) Gold 6248 CPU @ 2.50GHz, Debian 11

> bench_parse_revid:go().
* N: 10
* b2i + <<_:128>>  : 30
* decode_hex       : 3 (faster pct:90)
* l2i + <<_:128>>  : 8
* l2b + decode_hex : 4 (faster pct:50)
************

* N: 100
* b2i + <<_:128>>  : 54
* decode_hex       : 30 (faster pct:44)
* l2i + <<_:128>>  : 76
* l2b + decode_hex : 45 (faster pct:41)
************

* N: 500
* b2i + <<_:128>>  : 294
* decode_hex       : 159 (faster pct:46)
* l2i + <<_:128>>  : 411
* l2b + decode_hex : 238 (faster pct:42)
************

* N: 1000
* b2i + <<_:128>>  : 582
* decode_hex       : 316 (faster pct:46)
* l2i + <<_:128>>  : 820
* l2b + decode_hex : 465 (faster pct:43)
************

* N: 2500
* b2i + <<_:128>>  : 1472
* decode_hex       : 874 (faster pct:41)
* l2i + <<_:128>>  : 2154
* l2b + decode_hex : 1224 (faster pct:43)
************

ok

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment