Measuring performance of Java String.format() (or lack thereof)

aka “Why is String.format() SO slow?”

Background

More Specifically…

String key = String.format("%s.%s", keyspace, tableName);
String key = keyspace + "." + tableName; // or
key = new StringBuilder().append(keyspace)
.append('.').append(tableName).toString();

But Should String.format() Have Low Overhead?

So Let’s Ask Our Friend JMH To Have a Look

java  -jar target/microbenchmarks.jar StringConcatenation
m1_StringFormat           thrpt   15    61337.088 ±   654.370  ops/s
m2_StringBuilder thrpt 15 2683849.107 ± 22092.481 ops/s
m3_StringBuilderPrealloc thrpt 15 2654994.965 ± 36881.162 ops/s
m4_ManualConcatenation thrpt 15 2700825.252 ± 27906.924 ops/s

Test cases

So Let’s Unpack The Results

But What Does String.format() Do? (deeper dig)

// @Measurement(iterations = 5, time = 1)
@Measurement(iterations = 3600, time = 1)
java  -jar target/microbenchmarks.jar StringConcatenation.m1
~/bin/async-profiler -e cpu -d 30 -f ~/profile-string-format.txt 67640
ns  percent  samples  top
---------- ------- ------- ---
3100000000 10.97% 310 java.util.regex.Pattern$Start.match
2970000000 10.51% 297 java.util.regex.Pattern$GroupHead.match
2370000000 8.39% 237 java.util.Formatter.format
2110000000 7.47% 211 java.lang.AbstractStringBuilder.ensureCapacityInternal
1590000000 5.63% 159 jshort_disjoint_arraycopy
1420000000 5.02% 142 java.util.Formatter$FormatSpecifier.index
1340000000 4.74% 134 java.util.Formatter.parse
1270000000 4.49% 127 arrayof_jint_fill
1240000000 4.39% 124 java.util.regex.Pattern$BmpCharProperty.match
1100000000 3.89% 110 java.util.regex.Pattern.matcher
990000000 3.50% 99 java.util.Formatter$FormatSpecifier.width
980000000 3.47% 98 java.util.regex.Pattern$Branch.match
8
...

So Does This Matter?

Open Source developer, most known for Jackson data processor (nee “JSON library”), author of many, many other OSS libraries for Java, from ClassMate to Woodstox