Reverses Order of Bytes in Binary

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Reverses Order of Bytes in Binary

Сергей Прохоров-2
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
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Reverses Order of Bytes in Binary

Ivan Uemlianin
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, Сергей Прохоров <[hidden email]> 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
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-questions
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Reverses Order of Bytes in Binary

Сергей Прохоров-2
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 <[hidden email]>:
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, Сергей Прохоров <[hidden email]> 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
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-questions


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Reverses Order of Bytes in Binary

Sergej Jurečko
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, Сергей Прохоров <[hidden email]> 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 <[hidden email]>:
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, Сергей Прохоров <[hidden email]> 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
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Reverses Order of Bytes in Binary

Ivan Uemlianin
Testament to what a friendly language erlang is: the learner effortlessly arrives at the most fitting solution.

--
festina lente


On 10 Jan 2015, at 12:06, Sergej Jurecko <[hidden email]> wrote:

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, Сергей Прохоров <[hidden email]> 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 <[hidden email]>:
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, Сергей Прохоров <[hidden email]> 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
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Reverses Order of Bytes in Binary

Michael Uvarov-2
In reply to this post by Сергей Прохоров-2
there's another way:

reverse(Bin) when is_binary(Bin) ->

    S = bit_size(Bin),

    <<V:S/integer-little>> = Bin,

    <<V:S/integer-big>>.




On January 10, 2015 12:24:54 PM CET, "Сергей Прохоров" <seriy.pr@gmail.com> 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
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Reverses Order of Bytes in Binary

Harit Himanshu
Thanks a lot all, that was the only know I knew based on what I found in documentation, but I learnt lot other ways to do it.

Plus, One thing I learnt is how to measure performance, so Thank you all for your time and effort
+ Harit

On Sat, Jan 10, 2015 at 5:07 AM, Michael Uvarov <[hidden email]> wrote:
there's another way:

reverse(Bin) when is_binary(Bin) ->

    S = bit_size(Bin),

    <<V:S/integer-little>> = Bin,

    <<V:S/integer-big>>.




On January 10, 2015 12:24:54 PM CET, "Сергей Прохоров" <seriy.pr@gmail.com> 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
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Reverses Order of Bytes in Binary

Richard A. O'Keefe-2
In reply to this post by Michael Uvarov-2
I'm on holiday, so haven't been following mail regularly.
Why is reversing a binary useful?
How many times is the reversed binary to be traversed?
Is it practical to access the binary in reverse order
instead, acting _as if_ it had been reversed?



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Reverses Order of Bytes in Binary

Harit Himanshu
If this question is for me @ok, this is one of the exercise in Programming Erlang 2nd Edition. I am learning Erlang and sincerely trying my solutions, but also asking questions were I am very sure my solution is not correct or efficient.

Thank you
+ Harit Himanshu

On Sat, Jan 10, 2015 at 7:05 PM, <[hidden email]> wrote:
I'm on holiday, so haven't been following mail regularly.
Why is reversing a binary useful?
How many times is the reversed binary to be traversed?
Is it practical to access the binary in reverse order
instead, acting _as if_ it had been reversed?



_______________________________________________


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions