Big speedup (around 40%) of maps and arrays encoding by using proper tail recursion.

This commit is contained in:
Vincent de Phily 2010-06-28 14:17:44 +02:00
parent 279121f87f
commit 537322e3b5

View File

@ -145,15 +145,15 @@ pack_raw(Bin) when is_binary(Bin)->
pack_array(L) when is_list(L)->
case length(L) of
Len when Len < 16 ->
<< 2#1001:4, Len:4/integer-unit:1, (pack_array_(L))/binary >>;
<< 2#1001:4, Len:4/integer-unit:1, (pack_array_(L, <<>>))/binary >>;
Len when Len < 16#10000 -> % 65536
<< 16#DC:8, Len:16/big-unsigned-integer-unit:1,(pack_array_(L))/binary >>;
<< 16#DC:8, Len:16/big-unsigned-integer-unit:1,(pack_array_(L, <<>>))/binary >>;
Len ->
<< 16#DD:8, Len:32/big-unsigned-integer-unit:1,(pack_array_(L))/binary >>
<< 16#DD:8, Len:32/big-unsigned-integer-unit:1,(pack_array_(L, <<>>))/binary >>
end.
pack_array_([])-> <<>>;
pack_array_([Head|Tail])->
<< (pack(Head))/binary, (pack_array_(Tail))/binary >>.
pack_array_([], Acc) -> Acc;
pack_array_([Head|Tail], Acc) ->
pack_array_(Tail, <<Acc/binary, (pack(Head))/binary>>).
% FIXME! this should be tail-recursive and without lists:reverse/1
unpack_array_(<<>>, 0, RetList) -> {lists:reverse(RetList), <<>>};
@ -169,16 +169,16 @@ unpack_array_(Bin, RestLen, RetList) when is_binary(Bin)->
pack_map(M)->
case length(M) of
Len when Len < 16 ->
<< 2#1000:4, Len:4/integer-unit:1, (pack_map_(M))/binary >>;
<< 2#1000:4, Len:4/integer-unit:1, (pack_map_(M, <<>>))/binary >>;
Len when Len < 16#10000 -> % 65536
<< 16#DE:8, Len:16/big-unsigned-integer-unit:1, (pack_map_(M))/binary >>;
<< 16#DE:8, Len:16/big-unsigned-integer-unit:1, (pack_map_(M, <<>>))/binary >>;
Len ->
<< 16#DF:8, Len:32/big-unsigned-integer-unit:1, (pack_map_(M))/binary >>
<< 16#DF:8, Len:32/big-unsigned-integer-unit:1, (pack_map_(M, <<>>))/binary >>
end.
pack_map_([])-> <<>>;
pack_map_([{Key,Value}|Tail]) ->
<< (pack(Key))/binary,(pack(Value))/binary,(pack_map_(Tail))/binary >>.
pack_map_([], Acc) -> Acc;
pack_map_([{Key,Value}|Tail], Acc) ->
pack_map_(Tail, << Acc/binary, (pack(Key))/binary, (pack(Value))/binary>>).
% FIXME: write test for unpack_map/1
-spec unpack_map_(binary(), non_neg_integer(), [{term(), msgpack_term()}])->