summaryrefslogtreecommitdiff
path: root/lib/stdlib/test
diff options
context:
space:
mode:
authorBjörn Gustavsson <bjorn@erlang.org>2023-02-15 04:32:14 +0100
committerBjörn Gustavsson <bjorn@erlang.org>2023-02-16 07:32:00 +0100
commitbfb3c873bd1287149687b66f5c3098ddb7b1a11e (patch)
tree3891e9df4ae5e6598940176a927a94fca3cd67fa /lib/stdlib/test
parent81e9eb47c0cc9f3bd4bda77237aca2da5ef0ed4d (diff)
downloaderlang-bfb3c873bd1287149687b66f5c3098ddb7b1a11e.tar.gz
binary: Polish the hex encoding and decoding functions
The code for the `binary:encode_hex/1` and `binary:encode_hex/2` functions has been simplified. The simplified implementation has a more consistent runtime compared to the old implementation. To test the performance, I made a new `hex_bench` benchmark based on the `base64` benchmark: https://gist.github.com/bjorng/522470f313ac01d16156a597657f97bb For the old implementation, on my M1 Mac the results for the best case and worst case are as follows: Size: 1024*1024 (divisible by 8) fun binary:encode_hex/1: 1000 iterations in 1899 ms: 526 it/sec Size: 1024*1024 + 1 (not divisible by 2 through 7) fun binary:encode_hex/1: 1000 iterations in 5984 ms: 167 it/sec That is, the worst case is about three times slower than the best case. The simplifed encode function shows much less variation: Size: 1024*1024 (divisible by 8) fun binary:encode_hex/1: 1000 iterations in 1899 ms: 526 it/sec Size: 1024*1024 + 1 (not divisible by 8) fun binary:encode_hex/1: 1000 iterations in 2100 ms: 476 it/sec For the old implementation of `decode_hex/1`, the benchmark results are: fun binary:decode_hex/1: 1000 iterations in 28823 ms: 34 it/sec The results for the simplified implementation are: Size: 1024*1024 (divisible by 8) fun binary:decode_hex/1: 1000 iterations in 3041 ms: 328 it/sec Size: 1024*1024+1 (not divisible by 8) fun binary:decode_hex/1: 1000 iterations in 3144 ms: 318 it/sec That is, the simplified implementation is almost 10 times faster. All hex functions now raise exceptions with correct stack traces (with the function being called at the top of the stack trace) and error information.
Diffstat (limited to 'lib/stdlib/test')
-rw-r--r--lib/stdlib/test/binary_module_SUITE.erl33
1 files changed, 29 insertions, 4 deletions
diff --git a/lib/stdlib/test/binary_module_SUITE.erl b/lib/stdlib/test/binary_module_SUITE.erl
index 5ed05bfc55..954efae9b7 100644
--- a/lib/stdlib/test/binary_module_SUITE.erl
+++ b/lib/stdlib/test/binary_module_SUITE.erl
@@ -1462,11 +1462,15 @@ error_info(_Config) ->
{split, [<<1,2,3>>, {bm,make_ref()}, []]},
{split, [<<1,2,3>>, <<"2">>, [bad_option]]},
- {encode_hex, [{no,a,binary}], [allow_rename]},
+ {encode_hex, [{no,binary}]},
+ {encode_hex, [{no,binary}, lowercase]},
{encode_hex, [<<"foobar">>, othercase]},
- {decode_hex, [{no,a,binary}]},
- {decode_hex, [<<"000">>],[allow_rename]},
- {decode_hex, [<<"GG">>],[allow_rename]}
+ {encode_hex, [no_binary, othercase], [{1,".*"}, {2,".*"}]},
+
+ {decode_hex, [{no,binary}]},
+ {decode_hex, [<<"000">>]},
+ {decode_hex, [<<"GG">>]},
+ {decode_hex, [<<255>>]}
],
error_info_lib:test_error_info(binary, L).
@@ -1512,8 +1516,29 @@ hex_encoding(Config) when is_list(Config) ->
<<"foobar">> = binary:decode_hex(<<"666f6f626172">>),
<<"foobar">> = binary:decode_hex(<<"666f6F626172">>),
+
+ rand:seed(default),
+ io:format("*** SEED: ~p ***\n", [rand:export_seed()]),
+ Bytes = iolist_to_binary([rand:bytes(256), lists:seq(0, 255)]),
+ do_hex_roundtrip(Bytes),
+
ok.
+do_hex_roundtrip(Bytes) ->
+ UpperHex = binary:encode_hex(Bytes),
+ UpperHex = binary:encode_hex(Bytes, uppercase),
+ LowerHex = binary:encode_hex(Bytes, lowercase),
+
+ Bytes = binary:decode_hex(UpperHex),
+ Bytes = binary:decode_hex(LowerHex),
+
+ case Bytes of
+ <<_, Rest/binary>> ->
+ do_hex_roundtrip(Rest);
+ <<>> ->
+ ok
+ end.
+
%%%
%%% Utilities.
%%%