taro
taro

Reputation: 5832

Better way to reverse binary

I'm trying to reverse binary like this:

reverse(Bin) ->
    list_to_binary(lists:reverse([rev_bits(<<B>>) || B <- binary:bin_to_list(Bin)])).


rev_bits(<<A:1, B:1, C:1, D:1, E:1, F:1, G:1, H:1>>) ->
    <<H:1, G:1, F:1, E:1, D:1, C:1, B:1, A:1>>.

I don't like this code. Could you please advise better way to accomplish this routine?

Upvotes: 3

Views: 2608

Answers (3)

Led
Led

Reputation: 11

binary:encode_unsigned(binary:decode_unsigned(Bin, little)).

Upvotes: 1

Madalin Grigore-Enescu
Madalin Grigore-Enescu

Reputation: 1270

Better alternative:

rev(Binary) ->

   Size = erlang:size(Binary)*8,
   <<X:Size/integer-little>> = Binary,
   <<X:Size/integer-big>>.

Benchmark results of comparing to fenollp iteration method. The benchmark test was done calling both functions with a random binary containing 8192 random bytes:

Calling reverse 10 times

BENCHMARK my method: Calling reverse/1 function 10 times. Process took 0.000299 seconds BENCHMARK fenollp iteration method: Calling reverse_recursive/1 function 10 times. Process took 0.058528 seconds

Calling reverse 100 times

BENCHMARK my method: Calling reverse/1 function 100 times. Process took 0.002703 seconds BENCHMARK fenollp iteration method: Calling reverse_recursive/1 function 100 times. Process took 0.391098 seconds

The method proposed by me is usually at least 100 times faster.

Upvotes: 8

fenollp
fenollp

Reputation: 2496

Somewhat like your rev_bits function:

rev (<<>>, Acc) -> Acc;
rev (<<H:1/binary, Rest/binary>>, Acc) ->
    rev(Rest, <<H/binary, Acc/binary>>).

I believe binary concatenation is optimised so this should be quite fast already.

Edited: use clauses instead of case…of…end.

Upvotes: 8

Related Questions