reorder parser clauses and simplify escaping for performance

This commit is contained in:
alisdair sullivan 2014-12-05 03:16:58 +00:00
parent 9842a00b4d
commit 56c3bdb578
2 changed files with 79 additions and 85 deletions

View file

@ -23,7 +23,7 @@
-module(jsx_encoder).
-export([encoder/3, encode/1, encode/2, unzip/1]).
-export([encoder/3, encode/1, encode/2]).
-spec encoder(Handler::module(), State::any(), Config::list()) -> jsx:encoder().
@ -44,11 +44,10 @@ encode(Term, EntryPoint) -> encode_(Term, EntryPoint).
-endif.
-ifdef(maps_support).
encode(Map, _EntryPoint) when is_map(Map), map_size(Map) < 1 -> [start_object, end_object];
encode(Map, _EntryPoint) when is_map(Map), map_size(Map) < 1 ->
[start_object, end_object];
encode(Term, EntryPoint) when is_map(Term) ->
lists:flatten(
[start_object] ++ [ EntryPoint:encode(T, EntryPoint) || T <- unpack(Term) ] ++ [end_object]
);
[start_object] ++ unpack(Term, EntryPoint);
encode(Term, EntryPoint) -> encode_(Term, EntryPoint).
-endif.
@ -56,28 +55,29 @@ encode_([], _EntryPoint) -> [start_array, end_array];
encode_([{}], _EntryPoint) -> [start_object, end_object];
encode_([{_, _}|_] = Term, EntryPoint) ->
lists:flatten(
[start_object] ++ [ EntryPoint:encode(T, EntryPoint) || T <- unzip(Term) ] ++ [end_object]
);
[start_object] ++ unzip(Term, EntryPoint);
encode_(Term, EntryPoint) when is_list(Term) ->
lists:flatten(
[start_array] ++ [ EntryPoint:encode(T, EntryPoint) || T <- Term ] ++ [end_array]
);
[start_array] ++ unhitch(Term, EntryPoint);
encode_(Else, _EntryPoint) -> [Else].
unzip(List) -> unzip(List, []).
unzip([{K, V}|Rest], EntryPoint) when is_integer(K); is_binary(K); is_atom(K) ->
[K] ++ EntryPoint:encode(V, EntryPoint) ++ unzip(Rest, EntryPoint);
unzip([], _) -> [end_object].
unhitch([V|Rest], EntryPoint) ->
EntryPoint:encode(V, EntryPoint) ++ unhitch(Rest, EntryPoint);
unhitch([], _) -> [end_array].
unzip([], Acc) -> lists:reverse(Acc);
unzip([{K, V}|Rest], Acc) when is_binary(K); is_atom(K); is_integer(K) -> unzip(Rest, [V, K] ++ Acc).
-ifdef(maps_support).
unpack(Map) -> unpack(maps:keys(Map), Map, []).
unpack(Map, EntryPoint) -> unpack(Map, maps:keys(Map), EntryPoint).
unpack([], _, Acc) -> lists:reverse(Acc);
unpack([K|Rest], Map, Acc) when is_binary(K); is_atom(K); is_integer(K) ->
unpack(Rest, Map, [maps:get(K, Map), K] ++ Acc).
unpack(Map, [K|Rest], EntryPoint) when is_integer(K); is_binary(K); is_atom(K) ->
[K] ++ EntryPoint:encode(maps:get(K, Map), EntryPoint) ++ unpack(Map, Rest, EntryPoint);
unpack(_, [], _) -> [end_object].
-endif.