[erlang-questions] Reverses Order of Bytes in Binary

Sergej Jurecko sergej.jurecko@REDACTED
Sat Jan 10 13:06:30 CET 2015


Async version so results are less skewed by GC. 
With a larger bin it is more clear what the best solution is:

bin_reverse:reverse_test(crypto:rand_bytes(100000)).
"list"=15515
"tail_pos"=24061
"list_to_bin"=28627
"body_pos"=4781891

-module(bin_reverse).
-export([reverse_test/1]).


reverse_test(Bin) ->
    [
        async("body_pos",fun reverse_body_pos/1,Bin),
        async("tail_pos",fun reverse_tail_pos/1,Bin),
        async("list",fun reverse_list/1,Bin),
        async("list_to_bin",fun reverse_list_to_bin/1,Bin)
    ].

async(Name,Fun,Bin) ->
    spawn(fun() ->
        {T,_} = timer:tc(Fun,[Bin]),
        io:format("~p=~p~n",[Name,T])
    end).


reverse_tail_pos(Bin) ->
    reverse1(Bin, byte_size(Bin), <<>>).

reverse1(_, 0, Acc) -> Acc;
reverse1(Bin, Pos, Acc) ->
    reverse1(Bin, Pos - 1, <<Acc/binary, (binary:at(Bin, Pos - 1))>>).



reverse_body_pos(Bin) ->
    reverse2(Bin, byte_size(Bin)).

reverse2(_, 0) -> <<>>;
reverse2(Bin, Pos) ->
    <<(binary:at(Bin, Pos - 1)), (reverse2(Bin, Pos - 1))/binary >>.



reverse_list(Bin) ->
    list_to_binary(lists:reverse(binary_to_list(Bin))).



reverse_list_to_bin(Bin) ->
    reverse3(Bin, []).

reverse3(<<>>, Acc) -> list_to_binary(Acc);
reverse3(<<C,Bin/binary>>, Acc) -> reverse3(Bin, [C|Acc]).


On 10 Jan 2015, at 12:46, Сергей Прохоров <seriy.pr@REDACTED> wrote:

> Ok, looks like topicstarter's solution is the fastest one:
> 
> =======================
> -module(bin_reverse).
> -export([reverse_test/1]).
> 
> 
> reverse_test(Bin) ->
>     [
>      {"body_pos", timer:tc(fun reverse_body_pos/1, [Bin])},
>      {"tail_pos", timer:tc(fun reverse_tail_pos/1, [Bin])},
>      {"list", timer:tc(fun reverse_list/1, [Bin])},
>      {"list_to_bin", timer:tc(fun reverse_list_to_bin/1, [Bin])}
>     ].
> 
> 
> 
> reverse_tail_pos(Bin) ->
>     reverse1(Bin, byte_size(Bin), <<>>).
> 
> reverse1(_, 0, Acc) -> Acc;
> reverse1(Bin, Pos, Acc) ->
>     reverse1(Bin, Pos - 1, <<Acc/binary, (binary:at(Bin, Pos - 1))>>).
> 
> 
> 
> reverse_body_pos(Bin) ->
>     reverse2(Bin, byte_size(Bin)).
> 
> reverse2(_, 0) -> <<>>;
> reverse2(Bin, Pos) ->
>     <<(binary:at(Bin, Pos - 1)), (reverse2(Bin, Pos - 1))/binary >>.
> 
> 
> 
> reverse_list(Bin) ->
>     list_to_binary(lists:reverse(binary_to_list(Bin))).
> 
> 
> 
> reverse_list_to_bin(Bin) ->
>     reverse3(Bin, []).
> 
> reverse3(<<>>, Acc) -> list_to_binary(Acc);
> reverse3(<<C,Bin/binary>>, Acc) -> reverse3(Bin, [C|Acc]).
> 
> =======================
> 
> 24> bin_reverse:reverse_test(crypto:rand_bytes(100)).
> [{"body_pos",
>   {32,
>    <<247,128,13,6,1,53,110,148,74,210,196,126,234,115,180,
>      85,33,206,130,164,3,242,174,157,...>>}},
>  {"tail_pos",
>   {14,
>    <<247,128,13,6,1,53,110,148,74,210,196,126,234,115,180,
>      85,33,206,130,164,3,242,174,...>>}},
>  {"list",
>   {3,
>    <<247,128,13,6,1,53,110,148,74,210,196,126,234,115,180,
>      85,33,206,130,164,3,242,...>>}},
>  {"list_to_bin",
>   {13,
>    <<247,128,13,6,1,53,110,148,74,210,196,126,234,115,180,
>      85,33,206,130,164,3,...>>}}]
> 
> 2015-01-10 14:30 GMT+03:00 Ivan Uemlianin <ivan@REDACTED>:
> Remember lists:reverse/1 is implemented in C & does some non-erlangy things (IIRC) so should be jolly fast & efficient.  Unless binary_to_list/1 is v bad the OP's version is the best so far (imho).
> 
> Best wishes
> 
> Ivan
> 
> 
> --
> festina lente
> 
> 
> > On 10 Jan 2015, at 11:24, Сергей Прохоров <seriy.pr@REDACTED> wrote:
> >
> > Probably this one will be more effective
> >
> > reverse(Bin) ->
> >     reverse(Bin, byte_size(Bin)).
> >
> > reverse(_, 0) -> <<>>;
> > reverse(Bin, Pos) ->
> >     <<(binary:at(Bin, Pos - 1)), (reverse(Bin, Pos - 1))/binary >>.
> > _______________________________________________
> > erlang-questions mailing list
> > erlang-questions@REDACTED
> > http://erlang.org/mailman/listinfo/erlang-questions
> 
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20150110/ec559168/attachment.htm>


More information about the erlang-questions mailing list