Java9で文字列の結合の速度を確認する

# これは何
java9（earlyAccess版)で文字列の結合を実験したもの
※9 Build 134 

## テスト機のスペック
- Windows10
- Core i7
- メモリは8GB


# 実験に使ったソース
https://github.com/suzukitadashi/jmhTest/blob/master/jmhTest/src/main/java/jmhTest/MyBenchmarkStringLine.java

# JMHで実行した結果
- java8

```
Benchmark                                          Mode  Cnt    Score   Error  Units
jmhTest.MyBenchmarkStringLine.call1StringLine     thrpt   10  116.587 ± 0.733  ops/s
jmhTest.MyBenchmarkStringLine.call2StringConcat   thrpt   10   69.140 ± 2.958  ops/s
jmhTest.MyBenchmarkStringLine.call3StringBuffer   thrpt   10  105.525 ± 1.598  ops/s
jmhTest.MyBenchmarkStringLine.call4StringBuilder  thrpt   10  103.146 ± 4.292  ops/s
```

実行結果全文
https://github.com/suzukitadashi/jmhTest/blob/master/jmhTest/MyBenchmarkStringLine_java8%E5%AE%9F%E8%A1%8C%E7%B5%90%E6%9E%9C.txt

- java9

```
Benchmark                                          Mode  Cnt    Score   Error  Units
jmhTest.MyBenchmarkStringLine.call1StringLine     thrpt   10  262.700 ± 4.913  ops/s
jmhTest.MyBenchmarkStringLine.call2StringConcat   thrpt   10  136.718 ± 0.869  ops/s
jmhTest.MyBenchmarkStringLine.call3StringBuffer   thrpt   10   52.900 ± 0.437  ops/s
jmhTest.MyBenchmarkStringLine.call4StringBuilder  thrpt   10   56.853 ± 0.736  ops/s
```

実行結果全文
https://github.com/suzukitadashi/jmhTest/blob/master/jmhTest/MyBenchmarkStringLine_java9%E5%AE%9F%E8%A1%8C%E7%B5%90%E6%9E%9C.txt

# javapの結果
- java8
https://github.com/suzukitadashi/jmhTest/blob/master/jmhTest/MyBenchmarkStringLine_java8.txt

- java9
https://github.com/suzukitadashi/jmhTest/blob/master/jmhTest/MyBenchmarkStringLine_java9.txt

http://www.slideshare.net/bitter_fox/10java9java8 に載っている通り、java9だとinvokedynamic が使われていることが確認できる。


# まとめ ※java9はまだ正式版ではないので、正式版リリース後に改めて確認が必要！
- java8だと、Stringを＋でつなげたものとBuilder、Bufferで差異がそんなにないが、java9は＋で繋げたものが速い。
- java9はconcatで繋げたときも、Builderより速い…本当に？

# きつねさんにTwitterで教えていただいた。

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/deaf_tadashi">@deaf_tadashi</a> ありがとうございます．非常に面白い結果でびっくりしました．実際indy化ではあまり性能向上はそこまで無いと思っていたので．indy化の影響とは別にCompact Stringの影響も含まれているのかなと思いました．</p>&mdash; ミスティックきつね (@bitter_fox) <a href="https://twitter.com/bitter_fox/status/772360425694388225">2016年9月4日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/deaf_tadashi">@deaf_tadashi</a> Compact Stringは今までcharの配列で保存していたのをbyteの配列で保存するように使用というものです．また，英数字などのみの場合はUTF-16ではなくLatin-1という文字コードで保持するようになりました</p>&mdash; ミスティックきつね (@bitter_fox) <a href="https://twitter.com/bitter_fox/status/772361565093830656">2016年9月4日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/deaf_tadashi">@deaf_tadashi</a> これによって省メモリ化がされて，配列のコピーもその分高速になるのですが，ベンチマークでは数字でLatin-1に収まる物しか扱っていないので，String.+とString.concatがかなり高速になったのではないかと思います．</p>&mdash; ミスティックきつね (@bitter_fox) <a href="https://twitter.com/bitter_fox/status/772361928521818112">2016年9月4日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/deaf_tadashi">@deaf_tadashi</a> ぜひとも，日本語などのLatin-1に収まらない文字でベンチマークを取ると，違った結果になるかもしれないので，試してみていただけると嬉しいです．<br>文字列は色々な最適化が1つのバージョン内に入っているので，具体的にどれが影響したかは言い難いですがw</p>&mdash; ミスティックきつね (@bitter_fox) <a href="https://twitter.com/bitter_fox/status/772363441453486080">2016年9月4日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

# 追加テストを実施
## 実験用コード

### 半角英字のみ
https://github.com/suzukitadashi/jmhTest/blob/master/jmhTest/src/main/java/jmhTest/MyBenchmarkStringLineHankaku.java

### 全角文字のみ
https://github.com/suzukitadashi/jmhTest/blob/master/jmhTest/src/main/java/jmhTest/MyBenchmarkStringLineZenkaku.java

## 実験結果

### 半角英字のみ

- Java8

```
Benchmark                                                 Mode  Cnt    Score   Error  Units
jmhTest.MyBenchmarkStringLineHankaku.call1StringLine     thrpt   10  140.927 ± 1.069  ops/s
jmhTest.MyBenchmarkStringLineHankaku.call2StringConcat   thrpt   10   35.711 ± 0.432  ops/s
jmhTest.MyBenchmarkStringLineHankaku.call3StringBuffer   thrpt   10   96.962 ± 0.493  ops/s
jmhTest.MyBenchmarkStringLineHankaku.call4StringBuilder  thrpt   10   99.713 ± 1.548  ops/s
```

実行結果全文
https://github.com/suzukitadashi/jmhTest/blob/master/jmhTest/MyBenchmarkStringLineHankakuJava8Result.txt

- Java9

```
Benchmark                                                 Mode  Cnt   Score   Error  Units
jmhTest.MyBenchmarkStringLineHankaku.call1StringLine     thrpt   10  90.187 ± 2.961  ops/s
jmhTest.MyBenchmarkStringLineHankaku.call2StringConcat   thrpt   10  46.822 ± 3.277  ops/s
jmhTest.MyBenchmarkStringLineHankaku.call3StringBuffer   thrpt   10  68.937 ± 2.796  ops/s
jmhTest.MyBenchmarkStringLineHankaku.call4StringBuilder  thrpt   10  78.742 ± 2.665  ops/s
```

実行結果全文
https://github.com/suzukitadashi/jmhTest/blob/master/jmhTest/MyBenchmarkStringLineHankakuJava9Result.txt

### 全角文字のみ

- Java8

```
Benchmark                                                 Mode  Cnt    Score   Error  Units
jmhTest.MyBenchmarkStringLineZenkaku.call1StringLine     thrpt   10  141.394 ± 0.301  ops/s
jmhTest.MyBenchmarkStringLineZenkaku.call2StringConcat   thrpt   10   36.051 ± 0.287  ops/s
jmhTest.MyBenchmarkStringLineZenkaku.call3StringBuffer   thrpt   10   98.531 ± 0.644  ops/s
jmhTest.MyBenchmarkStringLineZenkaku.call4StringBuilder  thrpt   10   98.985 ± 3.572  ops/s
```

実行結果全文
https://github.com/suzukitadashi/jmhTest/blob/master/jmhTest/MyBenchmarkStringLineZenkakuJava8Result.txt

- Java9

```
Benchmark                                                 Mode  Cnt   Score   Error  Units
jmhTest.MyBenchmarkStringLineZenkaku.call1StringLine     thrpt   10  92.686 ± 0.299  ops/s
jmhTest.MyBenchmarkStringLineZenkaku.call2StringConcat   thrpt   10  49.554 ± 0.684  ops/s
jmhTest.MyBenchmarkStringLineZenkaku.call3StringBuffer   thrpt   10  56.950 ± 6.474  ops/s
jmhTest.MyBenchmarkStringLineZenkaku.call4StringBuilder  thrpt   10  69.917 ± 0.210  ops/s

```

実行結果全文
https://github.com/suzukitadashi/jmhTest/blob/master/jmhTest/MyBenchmarkStringLineZenkakuJava9Result.txt


# 追加テストをふまえたまとめ（再）
- 数値でない場合の結合速度は爆速になるどころか、遅くなっている。
- Java9はまだ開発途上ということもあってか、StringBuilderの処理速度も落ちているのが気になるところ。正式版リリースまでにはJava8同等の処理速度に戻るのであろうか？
- Javaのバージョンによって文字列の最適化だったり、内部処理の最適化だったりで文字列の操作が高速、なコーディング方法は異なってくる。
何でもかんでもStringBuilderを使えや、と言ってくる先輩エンジニアの言うことは無視して、疑問に思ったら自分で性能を確認しよう。
- このテストコードを書いた翌日に38度の熱を出したのはきっと知恵熱に違いない。