# [erlang-questions] Real basic binary manipulation question

Sun Jan 18 16:25:05 CET 2009

```Hello.

Thanks for this discussion (which was very usefull) and especially for
the trick with binary used as an accumulator (decompress2).

Here is another implementation (just to have as many variants as
possible :) using a deep list as an accumulator:

decompress3(Bin) when is_binary(Bin) ->
decompress3(Bin, []).

decompress3(<<0, Count, Tail/binary>>, Acc) ->
decompress3(Tail, [Acc, <<0:(Count * 8)>>]);
decompress3(<<>>, Acc) ->
list_to_binary(Acc).

It's slower than decompress2 but a bit faster (and more memory
consuming) than decompress1:

Eshell V5.6.5  (abort with ^G)
1> c(zrle), zrle:bm().
decompress1: 1520 (1525)
decompress2: 1110 (1104)
decompress3: 1470 (1477)
ok
2> c(zrle, [native]), zrle:bm().
decompress1: 1170 (1193)
decompress2: 720 (715)
decompress3: 1040 (1047)
ok

% -HERE-IS-THE-SOURCES-----------------------------

-module(zrle).
-compile(export_all).

bm() ->
bm(<<1,0,3,0,4,0,10,0,15,0,150>>, 500000).
bm(Bin, N) ->

statistics(runtime),
statistics(wall_clock),

repeat(fun() -> decompress(Bin) end, N),
{_, R1} = statistics(runtime),
{_, W1} = statistics(wall_clock),

repeat(fun() -> decompress2(Bin) end, N),
{_, R2} = statistics(runtime),
{_, W2} = statistics(wall_clock),

repeat(fun() -> decompress3(Bin) end, N),
{_, R3} = statistics(runtime),
{_, W3} = statistics(wall_clock),

io:format("decompress1: ~p (~p)~n", [R1, W1]),
io:format("decompress2: ~p (~p)~n", [R2, W2]),
io:format("decompress3: ~p (~p)~n", [R3, W3]).

repeat(_, 0) ->
ok;
repeat(Fun, N) ->
Fun(),
repeat(Fun, N - 1).

decompress(Bin) when is_binary(Bin) ->
decompress(Bin, []).

decompress(<<0, Count, Tail/binary>>, Acc) ->
decompress(Tail, [<<0:(Count * 8)>> | Acc]);
decompress(<<>>, Acc) ->
list_to_binary(lists:reverse(Acc)).

decompress2(Bin) when is_binary(Bin) ->
decompress2(Bin, <<>>).

decompress2(<<0, Count, Tail/binary>>, Acc) ->
decompress2(Tail, <<Acc/binary, 0:(Count * 8)>>);
decompress2(<<>>, Acc) ->
Acc.

decompress3(Bin) when is_binary(Bin) ->
decompress3(Bin, []).

decompress3(<<0, Count, Tail/binary>>, Acc) ->
decompress3(Tail, [Acc, <<0:(Count * 8)>>]);