[erlang-questions] Real basic binary manipulation question
Sergey S
ad.sergey@REDACTED
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(<<Head, Tail/binary>>, Acc) ->
decompress3(Tail, [Acc, Head]);
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(<<Head, Tail/binary>>, Acc) ->
decompress(Tail, [Head | 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(<<Head, Tail/binary>>, Acc) ->
decompress2(Tail, <<Acc/binary, Head>>);
decompress2(<<>>, Acc) ->
Acc.
decompress3(Bin) when is_binary(Bin) ->
decompress3(Bin, []).
decompress3(<<0, Count, Tail/binary>>, Acc) ->
decompress3(Tail, [Acc, <<0:(Count * 8)>>]);
decompress3(<<Head, Tail/binary>>, Acc) ->
decompress3(Tail, [Acc, Head]);
decompress3(<<>>, Acc) ->
list_to_binary(Acc).
--
Sergey
More information about the erlang-questions
mailing list