File 2342-stdlib-Fix-mime_decode-1-binary-matching-performance.patch of Package erlang

From ec7353ae51cc02c7b381a5142322a2b560bd0fab Mon Sep 17 00:00:00 2001
From: Jesse Stimpson <jstimpson@bandwidth.com>
Date: Fri, 24 Feb 2017 13:03:20 -0500
Subject: [PATCH] stdlib: Fix mime_decode/1 binary matching performance

Symptom: Throughput of base64:mime_decode/1 significantly lower than
base64:decode/1.

Problem: tail_contains_more/2 prevents compiler from delaying creation
of sub binaries.

Solution: Restructure mime_decode_binary/2 to use binary matching best
practices from the Efficiency Guide.

See ERL-366
---
 lib/stdlib/src/base64.erl | 67 +++++++++++++++++++++++++++--------------------
 1 file changed, 39 insertions(+), 28 deletions(-)

diff --git a/lib/stdlib/src/base64.erl b/lib/stdlib/src/base64.erl
index bf259e669..0c8d81791 100644
--- a/lib/stdlib/src/base64.erl
+++ b/lib/stdlib/src/base64.erl
@@ -219,38 +219,49 @@ mime_decode_binary(Result, <<0:8,T/bits>>) ->
     mime_decode_binary(Result, T);
 mime_decode_binary(Result0, <<C:8,T/bits>>) ->
     case element(C, ?DECODE_MAP) of
-	Bits when is_integer(Bits) ->
-	    mime_decode_binary(<<Result0/bits,Bits:6>>, T);
-	eq ->
-	    case tail_contains_more(T, false) of
-		{<<>>, Eq} ->
-		    %% No more valid data.
-		    case bit_size(Result0) rem 8 of
-			0 ->
-			    %% '====' is not uncommon.
-			    Result0;
-			4 when Eq ->
-			    %% enforce at least one more '=' only ignoring illegals and spacing
-			    Split =  byte_size(Result0) - 1,
-			    <<Result:Split/bytes,_:4>> = Result0,
-			    Result;
-			2 ->
-			    %% remove 2 bits
-			    Split =  byte_size(Result0) - 1,
-			    <<Result:Split/bytes,_:2>> = Result0,
-			    Result
-		    end;
-		{More, _} ->
-		    %% More valid data, skip the eq as invalid
-		    mime_decode_binary(Result0, More)
-	    end;
-	_ ->
-	    mime_decode_binary(Result0, T)
+        Bits when is_integer(Bits) ->
+            mime_decode_binary(<<Result0/bits,Bits:6>>, T);
+        eq ->
+            mime_decode_binary_after_eq(Result0, T, false);
+        _ ->
+            mime_decode_binary(Result0, T)
     end;
-mime_decode_binary(Result, <<>>) ->
+mime_decode_binary(Result, _) ->
     true = is_binary(Result),
     Result.
 
+mime_decode_binary_after_eq(Result, <<0:8,T/bits>>, Eq) ->
+    mime_decode_binary_after_eq(Result, T, Eq);
+mime_decode_binary_after_eq(Result0, <<C:8,T/bits>>, Eq) ->
+    case element(C, ?DECODE_MAP) of
+        bad ->
+            mime_decode_binary_after_eq(Result0, T, Eq);
+        ws ->
+            mime_decode_binary_after_eq(Result0, T, Eq);
+        eq ->
+            mime_decode_binary_after_eq(Result0, T, true);
+        Bits when is_integer(Bits) ->
+            %% More valid data, skip the eq as invalid
+            mime_decode_binary(<<Result0/bits,Bits:6>>, T)
+    end;
+mime_decode_binary_after_eq(Result0, <<>>, Eq) ->
+    %% No more valid data.
+    case bit_size(Result0) rem 8 of
+        0 ->
+            %% '====' is not uncommon.
+            Result0;
+        4 when Eq ->
+            %% enforce at least one more '=' only ignoring illegals and spacing
+            Split = byte_size(Result0) - 1,
+            <<Result:Split/bytes,_:4>> = Result0,
+            Result;
+        2 ->
+            %% remove 2 bits
+            Split = byte_size(Result0) - 1,
+            <<Result:Split/bytes,_:2>> = Result0,
+            Result
+    end.
+
 decode([], A) -> A;
 decode([$=,$=,C2,C1|Cs], A) ->
     Bits2x6 = (b64d(C1) bsl 18) bor (b64d(C2) bsl 12),
-- 
2.12.0

openSUSE Build Service is sponsored by