From fc80770ba7645d71a159c807c6aba7956a2eb394 Mon Sep 17 00:00:00 2001 From: Hans Bolinder Date: Tue, 7 Nov 2017 17:22:16 +0100 Subject: stdlib: Use binary_to_list in base64 when it is faster It is sometimes faster to use binary_to_list on input, at least when not considering time for garbage collections. The three functions all return a list, and the temporary list created by binary_to_list should be reclaimed very fast. The implementation from before is thus kept. --- lib/stdlib/src/base64.erl | 134 ++++------------------------------------------ 1 file changed, 11 insertions(+), 123 deletions(-) (limited to 'lib/stdlib/src/base64.erl') diff --git a/lib/stdlib/src/base64.erl b/lib/stdlib/src/base64.erl index 6311f3c86b..6ff6020e53 100644 --- a/lib/stdlib/src/base64.erl +++ b/lib/stdlib/src/base64.erl @@ -34,7 +34,7 @@ Base64String :: ascii_string(). encode_to_string(Bin) when is_binary(Bin) -> - encode_binary_to_string(Bin); + encode_to_string(binary_to_list(Bin)); encode_to_string(List) when is_list(List) -> encode_list_to_string(List). @@ -47,22 +47,6 @@ encode(Bin) when is_binary(Bin) -> encode(List) when is_list(List) -> encode_list(List, <<>>). -encode_binary_to_string(<<>>) -> - []; -encode_binary_to_string(<>) -> - [b64e(B1 bsr 2), - b64e((B1 band 3) bsl 4), $=, $=]; -encode_binary_to_string(<>) -> - [b64e(B1 bsr 2), - b64e(((B1 band 3) bsl 4) bor (B2 bsr 4)), - b64e((B2 band 15) bsl 2), $=]; -encode_binary_to_string(<>) -> - BB = (B1 bsl 16) bor (B2 bsl 8) bor B3, - [b64e(BB bsr 18), - b64e((BB bsr 12) band 63), - b64e((BB bsr 6) band 63), - b64e(BB band 63) | encode_binary_to_string(Ls)]. - encode_list_to_string([]) -> []; encode_list_to_string([B1]) -> @@ -141,7 +125,7 @@ mime_decode(List) when is_list(List) -> DataString :: ascii_string(). decode_to_string(Bin) when is_binary(Bin) -> - decode_binary_to_string(Bin); + decode_to_string(binary_to_list(Bin)); decode_to_string(List) when is_list(List) -> decode_list_to_string(List). @@ -150,7 +134,7 @@ decode_to_string(List) when is_list(List) -> DataString :: ascii_string(). mime_decode_to_string(Bin) when is_binary(Bin) -> - mime_decode_binary_to_string(Bin); + mime_decode_to_string(binary_to_list(Bin)); mime_decode_to_string(List) when is_list(List) -> mime_decode_list_to_string(List). @@ -339,67 +323,6 @@ mime_decode_list_to_string_after_eq([], B1, B2, eq) -> mime_decode_list_to_string_after_eq([], B1, B2, B3) -> binary_to_list(<>). -mime_decode_binary_to_string(<<0:8, Cs/bits>>) -> - mime_decode_binary_to_string(Cs); -mime_decode_binary_to_string(<>) -> - case b64d(C1) of - B1 when is_integer(B1) -> mime_decode_binary_to_string(Cs, B1); - _ -> mime_decode_binary_to_string(Cs) % eq is padding - end; -mime_decode_binary_to_string(<<>>) -> - []. - -mime_decode_binary_to_string(<<0:8, Cs/bits>>, B1) -> - mime_decode_binary_to_string(Cs, B1); -mime_decode_binary_to_string(<>, B1) -> - case b64d(C2) of - B2 when is_integer(B2) -> - mime_decode_binary_to_string(Cs, B1, B2); - _ -> mime_decode_binary_to_string(Cs, B1) % eq is padding - end. - -mime_decode_binary_to_string(<<0:8, Cs/bits>>, B1, B2) -> - mime_decode_binary_to_string(Cs, B1, B2); -mime_decode_binary_to_string(<>, B1, B2) -> - case b64d(C3) of - B3 when is_integer(B3) -> - mime_decode_binary_to_string(Cs, B1, B2, B3); - eq=B3 -> mime_decode_binary_to_string_after_eq(Cs, B1, B2, B3); - _ -> mime_decode_binary_to_string(Cs, B1, B2) - end. - -mime_decode_binary_to_string(<<0:8, Cs/bits>>, B1, B2, B3) -> - mime_decode_binary_to_string(Cs, B1, B2, B3); -mime_decode_binary_to_string(<>, B1, B2, B3) -> - case b64d(C4) of - B4 when is_integer(B4) -> - Bits4x6 = (B1 bsl 18) bor (B2 bsl 12) bor (B3 bsl 6) bor B4, - Octet1 = Bits4x6 bsr 16, - Octet2 = (Bits4x6 bsr 8) band 16#ff, - Octet3 = Bits4x6 band 16#ff, - [Octet1, Octet2, Octet3 | mime_decode_binary_to_string(Cs)]; - eq -> - mime_decode_binary_to_string_after_eq(Cs, B1, B2, B3); - _ -> mime_decode_binary_to_string(Cs, B1, B2, B3) - end. - -mime_decode_binary_to_string_after_eq(<<0:8, Cs/bits>>, B1, B2, B3) -> - mime_decode_binary_to_string_after_eq(Cs, B1, B2, B3); -mime_decode_binary_to_string_after_eq(<>=Cs0, B1, B2, B3) -> - case b64d(C) of - B when is_integer(B) -> - %% More valid data, skip the eq as invalid - case B3 of - eq -> mime_decode_binary_to_string(Cs, B1, B2, B); - _ -> mime_decode_binary_to_string(Cs0, B1, B2, B3) - end; - _ -> mime_decode_binary_to_string_after_eq(Cs, B1, B2, B3) - end; -mime_decode_binary_to_string_after_eq(<<>>, B1, B2, eq) -> - binary_to_list(<>); -mime_decode_binary_to_string_after_eq(<<>>, B1, B2, B3) -> - binary_to_list(<>). - decode_list([C1 | Cs], A) -> case b64d(C1) of ws -> decode_list(Cs, A); @@ -456,6 +379,14 @@ decode_binary(<>, A, B1, B2, B3) -> B4 -> decode_binary(Cs, <>) end. +only_ws_binary(<<>>, A) -> + A; +only_ws_binary(<>, A) -> + case b64d(C) of + ws -> only_ws_binary(Cs, A); + _ -> erlang:error(function_clause) + end. + decode_list_to_string([C1 | Cs]) -> case b64d(C1) of ws -> decode_list_to_string(Cs); @@ -500,49 +431,6 @@ only_ws([C | Cs], A) -> _ -> erlang:error(function_clause) end. -decode_binary_to_string(<>) -> - case b64d(C1) of - ws -> decode_binary_to_string(Cs); - B1 -> decode_binary_to_string(Cs, B1) - end; -decode_binary_to_string(<<>>) -> - []. - -decode_binary_to_string(<>, B1) -> - case b64d(C2) of - ws -> decode_binary_to_string(Cs, B1); - B2 -> decode_binary_to_string(Cs, B1, B2) - end. - -decode_binary_to_string(<>, B1, B2) -> - case b64d(C3) of - ws -> decode_binary_to_string(Cs, B1, B2); - B3 -> decode_binary_to_string(Cs, B1, B2, B3) - end. - -decode_binary_to_string(<>, B1, B2, B3) -> - case b64d(C4) of - ws -> decode_binary_to_string(Cs, B1, B2, B3); - eq when B3 =:= eq -> - only_ws_binary(Cs, binary_to_list(<>)); - eq -> - only_ws_binary(Cs, binary_to_list(<>)); - B4 -> - Bits4x6 = (B1 bsl 18) bor (B2 bsl 12) bor (B3 bsl 6) bor B4, - Octet1 = Bits4x6 bsr 16, - Octet2 = (Bits4x6 bsr 8) band 16#ff, - Octet3 = Bits4x6 band 16#ff, - [Octet1, Octet2, Octet3 | decode_binary_to_string(Cs)] - end. - -only_ws_binary(<<>>, A) -> - A; -only_ws_binary(<>, A) -> - case b64d(C) of - ws -> only_ws_binary(Cs, A); - _ -> erlang:error(function_clause) - end. - %%%======================================================================== %%% Internal functions %%%======================================================================== -- cgit v1.2.3