strings: Java Strings deep dive companion code (pool/intern, indy concat vs StringBuilder JMH, text blocks, string templates)
Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01KqJyCidz3ZgRyHABv2GVJh
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
literal == literal : true
|
||||
literal == new String : false
|
||||
literal.equals(new String) : true
|
||||
literal == c.intern() : true
|
||||
constant + literal == "hello" : true
|
||||
runtime concat == "hello" : false
|
||||
runtime concat.intern() == "hello": true
|
||||
built "java".intern() == the built instance : false
|
||||
built unseen string .intern() == the built instance: true
|
||||
@@ -0,0 +1,30 @@
|
||||
--- closing delimiter on its own line, aligned with the text ---
|
||||
{\n
|
||||
.."id":.1\n
|
||||
}\n
|
||||
|
||||
--- closing delimiter right after the last line (no final newline) ---
|
||||
{\n
|
||||
.."id":.1\n
|
||||
}
|
||||
--- closing delimiter 2 columns left of the text: 2 spaces of indentation survive ---
|
||||
..left\n
|
||||
|
||||
--- trailing spaces are stripped, but \s and \040 survive ---
|
||||
x....\n
|
||||
y.\n
|
||||
|
||||
--- backslash at end of line joins the lines ---
|
||||
one.line\n
|
||||
|
||||
--- escapes are processed after indentation is stripped ---
|
||||
tab: |\n
|
||||
|
||||
--- double quotes need no escape; only a run of three does ---
|
||||
say."hi".and."""\n
|
||||
|
||||
two identical text blocks are the same pooled instance: true
|
||||
equals the hand-written literal: true
|
||||
--- formatted() is the built-in way to interpolate ---
|
||||
Hello,.Ann!.You.are.30.\n
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
iteration 0: length=1 value=0
|
||||
iteration 1: length=2 value=01
|
||||
iteration 2: length=3 value=012
|
||||
iteration 3: length=4 value=0123
|
||||
iteration 4: length=5 value=01234
|
||||
characters copied in total across the loop results: 15
|
||||
n=20000: final length=20000, characters in all intermediate strings=200010000
|
||||
@@ -0,0 +1,25 @@
|
||||
$ javac ConcatShapes.java && javap -c -p ConcatShapes (method one)
|
||||
public static java.lang.String one(java.lang.String, int);
|
||||
Code:
|
||||
0: aload_0
|
||||
1: iload_1
|
||||
2: invokedynamic #7, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;I)Ljava/lang/String;
|
||||
7: areturn
|
||||
|
||||
$ javac -XDstringConcat=inline ConcatShapes.java && javap -c -p ConcatShapes (method one)
|
||||
public static java.lang.String one(java.lang.String, int);
|
||||
Code:
|
||||
0: new #7 // class java/lang/StringBuilder
|
||||
3: dup
|
||||
4: invokespecial #9 // Method java/lang/StringBuilder."<init>":()V
|
||||
7: ldc #10 // String user=
|
||||
9: invokevirtual #12 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||
12: aload_0
|
||||
13: invokevirtual #12 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||
16: ldc #16 // String n=
|
||||
18: invokevirtual #12 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||
21: iload_1
|
||||
22: invokevirtual #18 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
|
||||
25: invokevirtual #21 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
|
||||
28: areturn
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
$ javap -c -v ConcatShapes | grep -A3 BootstrapMethods
|
||||
BootstrapMethods:
|
||||
0: #39 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
|
||||
Method arguments:
|
||||
#37 user=\u0001 n=\u0001
|
||||
InnerClasses:
|
||||
@@ -0,0 +1,11 @@
|
||||
$ javac StringTemplate.java
|
||||
src/broken/StringTemplate.java:4: error: illegal escape character
|
||||
System.out.println(STR."Hello, \{name}");
|
||||
^
|
||||
1 error
|
||||
|
||||
$ javac --enable-preview --release 25 StringTemplate.java
|
||||
src/broken/StringTemplate.java:4: error: illegal escape character
|
||||
System.out.println(STR."Hello, \{name}");
|
||||
^
|
||||
1 error
|
||||
@@ -0,0 +1,4 @@
|
||||
bool CompactStrings = true {pd product} {default}
|
||||
bool OptimizeStringConcat = true {C2 product} {default}
|
||||
uintx StringTableSize = 65536 {product} {default}
|
||||
bool UseStringDeduplication = false {product} {default}
|
||||
@@ -0,0 +1,16 @@
|
||||
Benchmark (loop) Mode Cnt Score Error Units
|
||||
ConcatBenchmark.explicitBuilder N/A avgt 10 20.838 ± 2.629 ns/op
|
||||
ConcatBenchmark.formattedMethod N/A avgt 10 164.278 ± 12.164 ns/op
|
||||
ConcatBenchmark.plusExpression N/A avgt 10 20.448 ± 7.264 ns/op
|
||||
ConcatBenchmark.plusLatin1 N/A avgt 10 15.791 ± 4.953 ns/op
|
||||
ConcatBenchmark.plusUtf16 N/A avgt 10 23.185 ± 4.275 ns/op
|
||||
ConcatBenchmark.stringFormat N/A avgt 10 285.885 ± 133.980 ns/op
|
||||
LoopConcatBenchmark.loopBuilder 100 avgt 5 270.251 ± 128.322 ns/op
|
||||
LoopConcatBenchmark.loopBuilder 1000 avgt 5 2268.140 ± 888.134 ns/op
|
||||
LoopConcatBenchmark.loopBuilder 10000 avgt 5 24468.200 ± 8712.080 ns/op
|
||||
LoopConcatBenchmark.loopBuilderPresized 100 avgt 5 194.101 ± 168.069 ns/op
|
||||
LoopConcatBenchmark.loopBuilderPresized 1000 avgt 5 1682.224 ± 135.261 ns/op
|
||||
LoopConcatBenchmark.loopBuilderPresized 10000 avgt 5 20622.063 ± 16702.078 ns/op
|
||||
LoopConcatBenchmark.loopPlusEquals 100 avgt 5 2021.521 ± 648.577 ns/op
|
||||
LoopConcatBenchmark.loopPlusEquals 1000 avgt 5 73764.547 ± 11968.016 ns/op
|
||||
LoopConcatBenchmark.loopPlusEquals 10000 avgt 5 8939940.357 ± 2388632.875 ns/op
|
||||
@@ -0,0 +1,4 @@
|
||||
-------------------------------------------------------------------------------
|
||||
Test set: com.ankurm.strings.StringBehaviourTest
|
||||
-------------------------------------------------------------------------------
|
||||
Tests run: 8, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.252 s -- in com.ankurm.strings.StringBehaviourTest
|
||||
Reference in New Issue
Block a user