Why is finding one of many binaries faster than finding just one binary using `binary: match` in Erlang?

I tried to optimize the parser in Elixir, using binary:matchinstead of matching with the sample, when I discovered something strange: binary:match(Binary, [<<"z">>, <<"y">>])several times faster than binary:match(Binary, <<"z">>)even if the binary does not contain y, Here is the minimal program to play:

-module(a).
-compile(export_all).

one(Binary) ->
  binary:match(Binary, <<"z">>).

two(Binary) ->
  binary:match(Binary, [<<"z">>, <<"y">>]).

three(Binary) ->
  binary:match(Binary, [<<"z">>, <<"y">>, <<"x">>]).

main() ->
  As = binary:copy(<<"a">>, 10485760),
  Zs = binary:copy(<<"z">>, 10485760),
  Binary = <<As/binary, Zs/binary>>,
  io:format("~p~n", [timer:tc(?MODULE, one, [Binary])]),
  io:format("~p~n", [timer:tc(?MODULE, two, [Binary])]),
  io:format("~p~n", [timer:tc(?MODULE, three, [Binary])]).

And here is the output to a fairly fast OSX system:

{62556,{10485760,1}}
{18272,{10485760,1}}
{18558,{10485760,1}}

and not so fast Linux VPS:

{130249,{10485760,1}}
{39296,{10485760,1}}
{40805,{10485760,1}}

, , 10 a, 10 z, ["z", "y"] ["z", "y", "x"] 30% , "z", , y x. , .

, , ?

( Erlang/OTP 19 [erts-8.0.2].)

+4
1

[<<"z">>, <<"z">>] ( , [<<"z">>] ). , .

+2

Source: https://habr.com/ru/post/1656331/


All Articles