Files

2.1 KiB

strings

Companion code for the ankurm.com post "Java Strings Deep Dive: Interning, StringBuilder, Text Blocks, and the Concatenation Benchmark." Module strings in java-core-examples.

All explanation lives in the post; this module holds the runnable evidence and the captured output.

Versions

Component Version
JDK 25.0.4.1+1 (Temurin, LTS)
JMH 1.37
JUnit Jupiter 5.11.0
Hardware 2 vCPU x86-64 VM, shared with other jobs while measuring (timings are indicative, not a leaderboard)

Quickstart

export JDK25_HOME=/path/to/jdk-25
./scripts/run-all.sh        # rebuilds and regenerates everything in output/

run-all.sh ends with the JMH run, which takes a few minutes. JMH refuses to start if another JMH process holds /tmp/jmh.lock; wait for it rather than forcing it, or the numbers are worthless.

What is in here

File Shows Output
StringPoolDemo == vs equals, constant folding, runtime concatenation, intern() (including the already-pooled "java" surprise) 01
TextBlockDemo closing-delimiter position, indentation stripping, trailing spaces, \s, \<newline>, escape timing, formatted() 02
ConcatLoopDemo += in a loop allocates a new String each time; characters copied grows quadratically 03
ConcatShapes the same + expression compiled two ways; javap shows invokedynamic vs StringBuilder 04, 05
src/broken/StringTemplate.java STR."..." is a compile error on JDK 25, with and without --enable-preview 06
run-all.sh flags step StringTableSize, CompactStrings, OptimizeStringConcat, UseStringDeduplication defaults 07
ConcatBenchmark, LoopConcatBenchmark JMH: + vs StringBuilder vs String.format; Latin-1 vs UTF-16; += loop vs builder at 100/1000/10000 08
StringBehaviourTest 8 assertions behind the claims above 09

ConcatBenchmark uses 2 forks; LoopConcatBenchmark uses 1 fork; both 3 warmup and 5 measurement iterations of 1 s. Re-running moves the numbers by tens of percent but not the ordering.