absolutnie zrozumieć, że to nie jest odpowiedź na pytanie, po prostu chciałem wspomnieć, że jdk-9 wprowadza jeszcze jedną optymalizację, która jest domyślnie nazwie:
-XX: + CompactStrings
gdzie Latin1 znaków zajmują jeden bajt zamiast dwóch (przez znak). Z powodu tej zmiany wiele wewnętrznych metod String zmieniło się - działają one tak samo dla użytkownika, ale wewnętrznie są szybsze w wielu przypadkach.
Również w przypadku Ciągów do łączenia dwóch ciągów razem za pośrednictwem znaku plus, javac wygeneruje inny kod bajtowy.
Brak instrukcji kodu bajtowego, który łączy dwa ciągi razem więc javac będzie generować
StringBuilder # dołączyć
w back-end. Do czasu jdk-9.
Teraz delegatów kodu bajtowego do
StringConcatFactory # makeConcatWithConstants
lub
StringConcatFactory # makeConcat
pośrednictwem invokedynamic instrukcji kodu bajtowego:
aload_0
1: aload_2
2: aload_1
3: invokedynamiC#8, 0 // InvokeDynamiC#0:makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
8: areturn
Sposób połączenia dwóch łańcuchów jest teraz decyzją środowiska wykonawczego. może to być nadal StringBuilder lub może to być łączenie tablic bajtowych itp. Wszystko, co wiesz, że to się może zmienić, a dostaniesz najszybsze możliwe rozwiązanie.
EDIT
Właśnie debugowany i zobaczył, że istnieje sporo strategii, w jaki sposób dołączyć te ciągi:
private enum Strategy {
/**
* Bytecode generator, calling into {@link java.lang.StringBuilder}.
*/
BC_SB,
/**
* Bytecode generator, calling into {@link java.lang.StringBuilder};
* but trying to estimate the required storage.
*/
BC_SB_SIZED,
/**
* Bytecode generator, calling into {@link java.lang.StringBuilder};
* but computing the required storage exactly.
*/
BC_SB_SIZED_EXACT,
/**
* MethodHandle-based generator, that in the end calls into {@link java.lang.StringBuilder}.
* This strategy also tries to estimate the required storage.
*/
MH_SB_SIZED,
/**
* MethodHandle-based generator, that in the end calls into {@link java.lang.StringBuilder}.
* This strategy also estimate the required storage exactly.
*/
MH_SB_SIZED_EXACT,
/**
* MethodHandle-based generator, that constructs its own byte[] array from
* the arguments. It computes the required storage exactly.
*/
MH_INLINE_SIZED_EXACT
}
Domyślna istota:
MH_INLINE_SIZED_EXACT
Myślę, że to jest (jak się domyślacie) * głównie * koszty runtime de-duplikacji. –
Nie G1GC, ale sama deduplikacja może zostać uznana za nową. – Holger