Java string concatenation '+' behavior: compiler-dependent optimization limits
0 reputation · 25 Apr 2021, 04:28 UTC
0 reputation · 25 Apr 2021, 04:28 UTC
The objective is to determine the specific conditions under which different Java compilers translate the string concatenation operator (+) into StringBuilder append calls versus other strategies like String.concat.
According to the Java Language Specification (§15.18.1.2), implementations are permitted to use any strategy to evaluate string concatenation, meaning the exact behavior is not mandated. While Oracle's javac typically translates non-constant concatenation to StringBuilder, other compilers such as Eclipse ECJ may apply different heuristics or thresholds. This variance creates uncertainty when writing performance-critical code, as the generated bytecode may differ across environments, potentially impacting memory allocation and execution speed.
javac to decide between StringBuilder and String.concat for non-constant expressions?+ operator?javap -c to confirm the compiler's chosen concatenation strategy?34775 reputation · 25 Apr 2021, 07:17 UTC
Both javac and Eclipse ECJ generally emit a StringBuilder chain for any concatenation that involves more than two operands or is not a simple binary expression. For a two‑operand expression where the left side is a string literal and the right side is a single String value, they may replace the StringBuilder with a direct call to String.concat to avoid creating a temporary builder.
javacString.concat if the right operand is a String or a known constant.StringBuilder chain.invokedynamic via StringConcatFactory when the –XDstringConcat=enabled flag is set.String.concat for two operands even when the right side is a non‑constant string expression.StringBuilder.–XDstringConcat=enabled flag for invokedynamic in recent releases.StringBuilder chain: new StringBuilder, dup, invokespecial <init>, several invokevirtual append calls, followed by invokevirtual toString.concat: aload_#, invokevirtual java/lang/String.concat.invokedynamic instruction referencing StringConcatFactory.public class Test {
static String two(String a) { return "a" + a; }
static String three(String a, String b) { return a + b + "c"; }
}
javac Test.java # OpenJDK
ecj Test.java # Eclipse ECJ
javap -c Test
To see the invokedynamic path, compile with
javac -XDstringConcat=enabled Test.java
or for ECJ, use the equivalent flag if available.
To tailor the recommendation precisely, please specify the exact compiler version and any flags you use (e.g., –XDstringConcat=enabled). The heuristics can shift between releases.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.