SlideShare a Scribd company logo
3
Most read
6
Most read
8
Most read
Java 9 で
文字列結合の
処理が変わるぞ!
準備はいいか!?
@YujiSoftware
問題
• +演算子による文字列結合は最終的に
どのような処理になる?
private static String test(String str, int value) {
return "ABC” + str + value;
}
Java 8 までは
• コンパイル時に StringBuilder を使った処理に
なる
private static String test(String str, int value) {
return new StringBuilder()
.append("ABC")
.append(str)
.append(value)
.toString();
}
Java 9 では
• InvokeDynamic で、実行時に処理を作る
private static String test(String str, int value) {
return InvokeDynamic
#1:makeConcatWithConstants:
(II)Ljava/lang/String;
}
そして…
InvokeDynamic の結果!
• 「byte配列を生成し、そこに文字を詰める処
理」が出来上がる!
private static String test(String str, int value) {
int length = (文字列の長さを計算);
byte[] buf = new byte[length];
int index = buf.length;
index = StringConcatHelper.prepend(index, buf, coder, value);
index = StringConcatHelper.prepend(index, buf, coder, str);
index = StringConcatHelper.prepend(index, buf, coder, "ABC");
return new String(buf,coder);
}
+演算子による文字列結合で
StringBuilder は
使わなくなった!
どういうこと?
• JEP280 (Indy String Concatenation) の対応
– 再コンパイルなしで、文字列結合を最適な処理に
変更できるようにする
InvokeDynamic を使って、実行時に処理を作るように
変更する
– そのついでに、より最適化された処理を
作るようにしよう!(ストレッチゴール)
いくつかの案を試すことになった
実装された案
案(ストラテジー) 概要
BC_SB StringBuilderを使ったバイトコードを生成する(既存と同様)
BC_SB_SIZED StringBuilderを使ったバイトコードを生成する。
加えて、必要な配列のサイズを「推定」する。
BC_SB_SIZED_EXACT StringBuilderを使ったバイトコードを生成する。
加えて、必要な配列のサイズを「正確に計算」する。
MH_SB_SIZED MethodHandleベースのジェネレータを使って、最終的に
StringBuilder を呼び出す。
加えて、必要な配列のサイズを「推定」する。
MH_SB_SIZED_EXACT MethodHandleベースのジェネレータを使って、最終的に
StringBuilder を呼び出す。
加えて、必要な配列のサイズを「正確に計算」する。
MH_INLINE_SIZED_EXACT MethodHandleベースのジェネレータを使って、独自にbyte
配列を構築する。
必要な配列のサイズを「正確に計算」する。
※ 起動オプション –D:java.lang.invoke.stringConcat=(ストラテジー名) で変更可能
採用された案
• MH_INLINE_SIZED_EXACT が採用された
– 唯一、StringBuilder を使わない実装
• 特徴
– 各APIをMethodHandleでコールする処理を作る
– 文字列を格納する配列の長さを、最初に厳密に
計算する
• 足りなくなったら新しく配列を作り直す、という
StringBuilderの無駄を避ける
文字列結合の処理は
どうやって作られるのか
java.lang.invoke.StringConcatFactory
#makeConcatWithConstants の実装// Start building the combinator tree. The tree "starts" with (<parameters>)String, and "finishes"
// with the (int, byte[], byte)String in String helper. The combinators are assembled bottom-up,
// which makes the code arguably hard to read.
// Drop all remaining parameter types, leave only helper arguments:
MethodHandle mh;
mh = MethodHandles.dropArguments(NEW_STRING, 3, ptypes);
// Mix in prependers. This happens when (byte[], int, byte) = (storage, index, coder) is already
// known from the combinators below. We are assembling the string backwards, so "index" is the
// *ending* index.
for (RecipeElement el : recipe.getElements()) {
// Do the prepend, and put "new" index at index 1
mh = MethodHandles.dropArguments(mh, 2, int.class);
switch (el.getTag()) {
case TAG_CONST: {
Object cnst = el.getValue();
MethodHandle prepender = MethodHandles.insertArguments(prepender(cnst.getClass()), 3, cnst)
mh = MethodHandles.foldArguments(mh, 1, prepender,
2, 0, 3 // index, storage, coder
);
break;
}
case TAG_ARG: {
int pos = el.getArgPos();
MethodHandle prepender = prepender(ptypes[pos]);
mh = MethodHandles.foldArguments(mh, 1, prepender,
2, 0, 3, // index, storage, coder
4 + pos // selected argument
);
break;
さっぱり分からん
(´・ω・`)
作戦変更
• JIT Watch で、 makeConcatWithConstants
メソッドにより生成された処理を確認
• JIT Watchとは?
– ソースコードと、それをコンパイルしたバイトコード、さらに
実行時のアセンブラを並べて比較できるツール
– どのような処理が実行されたのかがひと目でわかる
生成された処理
0x000001df3b29f540: cmp $0xfa0a1f00,%r10d
0x000001df3b29f547: jg L002f
0x000001df3b29f54d: cmp $0xc4653600,%r10d
0x000001df3b29f554: jle L0050 ;*if_icmple {reexecute=0 rethrow=0 return_oop=0}
; - java.lang.Integer::stringSize@24 (line 542)
; - java.lang.StringConcatHelper::mixLen@2 (line 96)
; - java.lang.invoke.DirectMethodHandle$Holder::invokeStatic@11
; - java.lang.invoke.LambdaForm$BMH/400136488::reinvoke@48
; - java.lang.invoke.LambdaForm$MH/1879034789::linkToTargetMethod@6
; - Test::test@17 (line 15)
0x000001df3b29f55a: mov $0x8,%ecx
0x000001df3b29f55f: jmp L0003
L0002: mov $0x2,%ecx
L0003: inc %ecx ;*iinc {reexecute=0 rethrow=0 return_oop=0}
; - java.lang.Integer::stringSize@36 (line 541)
; - java.lang.StringConcatHelper::mixLen@2 (line 96)
; - java.lang.invoke.DirectMethodHandle$Holder::invokeStatic@11
; - java.lang.invoke.LambdaForm$BMH/400136488::reinvoke@48
; - java.lang.invoke.LambdaForm$MH/1879034789::linkToTargetMethod@6
; - Test::test@17 (line 15)
L0004: mov %ecx,%r8d
0x000001df3b29f56b: add $0x5,%r8d ;*iadd {reexecute=0 rethrow=0 return_oop=0}
時間がないので流れだけ
説明すると…
Phase 1. byte配列を作る
1. 結合する各文字列の長さを計算する
2. 合計分の長さのbyte配列を作成する
byte[] buf = new byte[10]
例:
“ABC” → 3
1357 → 5
obj → obj.toString().length() → 3
Phase 2. byte配列に文字列を詰める
3. 末尾の方から、byte配列に文字を詰めていく
– 末尾から処理する理由は不明
• メモリのアクセス効率がいい?
A B C 1 3 5 7 o b j
“A B C”
1 3 5 7
o b j
byte配列
Phase 3. 文字列にする
4. 作った配列を String にする
new String(buf, coder);
A B C 1 3 5 7 o b j
完成!
どのぐらい速くなったか
• 文字列にもよるが、1倍~3倍程度速くなる
• ただし、最初だけ少し遅い
– InvokeDynamic で処理を作る必要があるため
• 詳しくは、JEP280 の資料を参照
– http://cr.openjdk.java.net/~shade/8085796/notes
.txt
まとめ
• Java 9 で + 演算による文字列結合の処理が
変わった
– StringBuilder が使われなくなった
– パフォーマンスも向上した
• Java 9 を使う理由がまた一つ増えた!
• ぜひアップデートした知識を使って、Java を
アップデートしましょう!
Java 9 で
文字列結合の
処理が変わるぞ!
準備はいいか!?
@YujiSoftware
ちなみに
• 後日、詳細をブログにまとめる予定
• 地平線に行くで検索
– http://d.hatena.ne.jp/chiheisen/

More Related Content

PDF
JavaでWebサービスを作り続けるための戦略と戦術 JJUG-CCC-2018-Spring-g1
PDF
PostgreSQLアンチパターン
PDF
入門 シェル実装
PDF
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
PPTX
Metaspace
PDF
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
PDF
macOSの仮想化技術について ~Virtualization-rs Rust bindings for virtualization.framework ~
PDF
広告配信のための高速疎ベクトル検索エンジンの開発@WebDBフォーラム2015 #webdbf2015
JavaでWebサービスを作り続けるための戦略と戦術 JJUG-CCC-2018-Spring-g1
PostgreSQLアンチパターン
入門 シェル実装
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
Metaspace
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
macOSの仮想化技術について ~Virtualization-rs Rust bindings for virtualization.framework ~
広告配信のための高速疎ベクトル検索エンジンの開発@WebDBフォーラム2015 #webdbf2015

What's hot (20)

PDF
WebAssemblyのWeb以外のことぜんぶ話す
PDF
雑なMySQLパフォーマンスチューニング
PDF
MySQL 5.7にやられないためにおぼえておいてほしいこと
PDF
ソーシャルゲーム案件におけるDB分割のPHP実装
PDF
Protocol Buffers 入門
PDF
人生がときめくAPIテスト自動化 with Karate
PDF
今日からできる!簡単 .NET 高速化 Tips
PDF
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
PDF
会社でClojure使ってみて分かったこと
PDF
ソーシャルゲームの為のデータベース設計
PPTX
冬のLock free祭り safe
PDF
DBスキーマもバージョン管理したい!
PDF
MySQLで論理削除と正しく付き合う方法
PDF
MySQLアンチパターン
PDF
Spring Bootをはじめる時にやるべき10のこと
PDF
CRDT in 15 minutes
PDF
規格書で読むC++11のスレッド
PDF
ヤフー社内でやってるMySQLチューニングセミナー大公開
PDF
そんなトランザクションマネージャで大丈夫か?
PDF
PostgreSQLレプリケーション10周年!徹底紹介!(PostgreSQL Conference Japan 2019講演資料)
WebAssemblyのWeb以外のことぜんぶ話す
雑なMySQLパフォーマンスチューニング
MySQL 5.7にやられないためにおぼえておいてほしいこと
ソーシャルゲーム案件におけるDB分割のPHP実装
Protocol Buffers 入門
人生がときめくAPIテスト自動化 with Karate
今日からできる!簡単 .NET 高速化 Tips
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
会社でClojure使ってみて分かったこと
ソーシャルゲームの為のデータベース設計
冬のLock free祭り safe
DBスキーマもバージョン管理したい!
MySQLで論理削除と正しく付き合う方法
MySQLアンチパターン
Spring Bootをはじめる時にやるべき10のこと
CRDT in 15 minutes
規格書で読むC++11のスレッド
ヤフー社内でやってるMySQLチューニングセミナー大公開
そんなトランザクションマネージャで大丈夫か?
PostgreSQLレプリケーション10周年!徹底紹介!(PostgreSQL Conference Japan 2019講演資料)
Ad

Viewers also liked (20)

PDF
Java SE 9の紹介: モジュール・システムを中心に
PDF
JJUG初心者のためのJava/JJUG講座
PDF
劇的改善 Ci4時間から5分へ〜私がやった10のこと〜
PDF
Java9を迎えた今こそ!Java本格(再)入門
PPTX
Dockerで始める Java EE アプリケーション開発 for JJUG CCC 2017
PDF
Selenide or Geb 〜あなたはその時どちらを使う〜
PDF
ユニットテストのアサーション 流れるようなインターフェースのAssertJを添えて 入門者仕立て
PDF
JVM上で動くPython処理系実装のススメ
PPTX
サーバサイド Kotlin
PPTX
マルチクラウドデータ連携Javaアプリケーションの作り方
PPTX
高速なソートアルゴリズムを書こう!!
PDF
Another compilation method in java - AOT (Ahead of Time) compilation
PDF
Business Process Modeling in Goldman Sachs @ JJUG CCC Fall 2017
PPTX
将来 自分で サービスを持ちたいエンジニアの葛藤
PPTX
Javaアプリケーションの モダナイゼーションアプローチ
PPTX
サンプルアプリケーションで学ぶApache Cassandraを使ったJavaアプリケーションの作り方
PPTX
Java を今すぐダウンロードしてみたお話
PDF
Open Liberty: オープンソースになったWebSphere Liberty
PDF
CPUから見たG1GC
PDF
CDNのトラフィックエンジニアリング:CDNの現状とSDNの可能性
Java SE 9の紹介: モジュール・システムを中心に
JJUG初心者のためのJava/JJUG講座
劇的改善 Ci4時間から5分へ〜私がやった10のこと〜
Java9を迎えた今こそ!Java本格(再)入門
Dockerで始める Java EE アプリケーション開発 for JJUG CCC 2017
Selenide or Geb 〜あなたはその時どちらを使う〜
ユニットテストのアサーション 流れるようなインターフェースのAssertJを添えて 入門者仕立て
JVM上で動くPython処理系実装のススメ
サーバサイド Kotlin
マルチクラウドデータ連携Javaアプリケーションの作り方
高速なソートアルゴリズムを書こう!!
Another compilation method in java - AOT (Ahead of Time) compilation
Business Process Modeling in Goldman Sachs @ JJUG CCC Fall 2017
将来 自分で サービスを持ちたいエンジニアの葛藤
Javaアプリケーションの モダナイゼーションアプローチ
サンプルアプリケーションで学ぶApache Cassandraを使ったJavaアプリケーションの作り方
Java を今すぐダウンロードしてみたお話
Open Liberty: オープンソースになったWebSphere Liberty
CPUから見たG1GC
CDNのトラフィックエンジニアリング:CDNの現状とSDNの可能性
Ad

Similar to JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc (20)

PDF
Java SE 7 InvokeDynamic in JRuby
PDF
バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)
PDF
Java 7 invokedynamic の概要
PPTX
jvmlang.daitokai 1.0.0 MinCamlJを作ってみた
PDF
Adaptive optimization of JIT compiler
PDF
20171212 titech lecture_ishizaki_public
PDF
静かに変わってきたクラスファイルを詳細に調べて楽しむ(JJUG CCC 2024 Fall講演資料)
PDF
gen-class とバイトコード(第3回 gen-class 勉強会資料)
PPTX
ネイティブコードを語る
PDF
Dalvikバイトコードリファレンスの読み方 改訂版
PPT
Eclipse を使った java 開発 111126 杉浦
PDF
明日から使える Java SE 7
PDF
20141224 titech lecture_ishizaki_public
PDF
JDK 10 へようこそ
PPTX
PDF
Unit test in android
PDF
XunitとMoq 公開用
PDF
Var handles jjug_ccc_spring_2018
PDF
Groovy indy 20120222
PDF
from old java to java8 - KanJava Edition
Java SE 7 InvokeDynamic in JRuby
バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)
Java 7 invokedynamic の概要
jvmlang.daitokai 1.0.0 MinCamlJを作ってみた
Adaptive optimization of JIT compiler
20171212 titech lecture_ishizaki_public
静かに変わってきたクラスファイルを詳細に調べて楽しむ(JJUG CCC 2024 Fall講演資料)
gen-class とバイトコード(第3回 gen-class 勉強会資料)
ネイティブコードを語る
Dalvikバイトコードリファレンスの読み方 改訂版
Eclipse を使った java 開発 111126 杉浦
明日から使える Java SE 7
20141224 titech lecture_ishizaki_public
JDK 10 へようこそ
Unit test in android
XunitとMoq 公開用
Var handles jjug_ccc_spring_2018
Groovy indy 20120222
from old java to java8 - KanJava Edition

More from YujiSoftware (8)

PPTX
ラムダのコンパイル結果を5分で説明するよ​
PPTX
Javaはどれだけ速いのか
PPTX
Java をクラッシュさせて遊んでみよう!
PPTX
技術書を読むと眠くなる!これを解決するために取った10の対策
PPTX
JVM言語を使ってみようの歌
PPTX
AtCoderで始めるテスト駆動開発
PPTX
Javaでマサカリ投げてみた
PPTX
ジャバのはなし、JAVAのはなし、Javaのはなし
ラムダのコンパイル結果を5分で説明するよ​
Javaはどれだけ速いのか
Java をクラッシュさせて遊んでみよう!
技術書を読むと眠くなる!これを解決するために取った10の対策
JVM言語を使ってみようの歌
AtCoderで始めるテスト駆動開発
Javaでマサカリ投げてみた
ジャバのはなし、JAVAのはなし、Javaのはなし

JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc