From bee8f839296e0424ddaf3a235ca285c2525cd28e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Fri, 24 Feb 2017 16:01:32 +0100 Subject: v3_core: Combine binary strings to larger integers Binary construction that mixes long literal strings with variables will make Dialyzer slow. Example: <<"long string (thousand of characters)",T/binary>> The string literals in binary construction is translated to one binary segment per character; all those segments will slow down Dialyzer. We can speed up Dialyzer if we combine several characters (up to 256) to a signle segment in the binary. It will also slightly speed up the compiler. This optimization will make core listings file with binary strings harder to read, but they were not that easy to read before this change. ERL-308 --- lib/compiler/src/v3_core.erl | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'lib/compiler') diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index 14cd41ae27..8dea7ec03a 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -1059,13 +1059,30 @@ count_bits(Int) -> count_bits_1(0, Bits) -> Bits; count_bits_1(Int, Bits) -> count_bits_1(Int bsr 64, Bits+64). -bin_expand_strings(Es) -> - foldr(fun ({bin_element,Line,{string,_,S},Sz,Ts}, Es1) -> - foldr(fun (C, Es2) -> - [{bin_element,Line,{char,Line,C},Sz,Ts}|Es2] - end, Es1, S); - (E, Es1) -> [E|Es1] - end, [], Es). +bin_expand_strings(Es0) -> + foldr(fun ({bin_element,Line,{string,_,S},{integer,_,8},_}, Es) -> + bin_expand_string(S, Line, 0, 0) ++ Es; + ({bin_element,Line,{string,_,S},Sz,Ts}, Es1) -> + foldr( + fun (C, Es) -> + [{bin_element,Line,{char,Line,C},Sz,Ts}|Es] + end, Es1, S); + (E, Es) -> + [E|Es] + end, [], Es0). + +bin_expand_string(S, Line, Val, Size) when Size >= 2048 -> + Combined = make_combined(Line, Val, Size), + [Combined|bin_expand_string(S, Line, 0, 0)]; +bin_expand_string([H|T], Line, Val, Size) -> + bin_expand_string(T, Line, (Val bsl 8) bor H, Size+8); +bin_expand_string([], Line, Val, Size) -> + [make_combined(Line, Val, Size)]. + +make_combined(Line, Val, Size) -> + {bin_element,Line,{integer,Line,Val}, + {integer,Line,Size}, + [integer,{unit,1},unsigned,big]}. expr_bin_1(Es, St) -> foldr(fun (E, {Ces,Esp,St0}) -> -- cgit v1.2.3