Parentheses prevent optimal decision about fpc_ansistr_concat_multi.
Both explicit parentheses and str += second_str + third_str
which becomes str := str + (second_str + third_str)
.
For the example below, t := t + (GetString + (GetString + GetString))
generates 20–25% slower and 25–30% larger code than t + GetString + GetString + GetString
.
{$mode objfpc} {$longstrings on}
function GetString: string;
begin
result := Copy('', 1, 0);
end;
label
A0, A1, D0, D1;
var
t: string;
begin
A0:
t := '';
// Produces one fpc_ansistr_concat_multi.
t := t + GetString + GetString + GetString;
A1:
writeln('t + GetString + GetString + GetString: ', CodePointer(@A1) - CodePointer(@A0), ' b');
t := '';
// Produces one fpc_ansistr_decr_ref on a temporary, one fpc_ansistr_concat_multi and then one fpc_ansistr_concat.
t := t + (GetString + GetString + GetString);
t := '';
// Same as above.
t += GetString + GetString + GetString;
D0:
t := '';
// Produces two fpc_ansistr_decr_ref’s on temporaries and three fpc_ansistr_concat’s.
t := t + (GetString + (GetString + GetString));
D1:
writeln('t + (GetString + (GetString + GetString)): ', CodePointer(@D1) - CodePointer(@D0), ' b');
end.
t + GetString + GetString + GetString: 95 b
t + (GetString + (GetString + GetString)): 122 b