今までのパフォーマンスコーディングは既に古いかもしれない

性能向上するためにJavaプログラムを見直ししてる日々。今は昔こう書けばパフォーマンスが上がるという定説は通用しないのを実感した。特に下記2点については使えない@J2SE1.4.2。

  • 文字列結合にはStringBufferを使いましょう
  • メソッドの修飾子によって速度が変わる

J2SE1.3を使用していた時、性能測定をするために記述した簡単なパフォーマンステストプログラムを1.4で動かしてみた。私がまめなのか、結果がちゃんとReadme.txtとして残っているのがうれしいが、その結果と比較して唖然とする。

  • 文字列結合にはStringBufferを使いましょう

これはバイトコードを見れば一目瞭然な訳だが、文字列結合は、"+"を使用したほうが1結合につきバイトコードが2命令減る(後は全く一緒)。元々そうだったのか、Javacが優秀になったのか!?
ただ、J2SE1.4.2として結合された文字列が16文字を超える場合で、サイズをあらかじめ知ることができている場合は、StringBufferに初期サイズを与えたほうが確実に速い。
追記 2005/02/08 http://d.hatena.ne.jp/yasuff11/20050208

  • メソッド修飾子によって速度が変わる


2002/11/29 SUN 1.3
private : 1412 (ms)
private final : 1422 (ms)
private static final: 1422 (ms)
protected :11426 (ms)
protected final : 1422 (ms)
public :11467 (ms)
2005/01/25 SUN 1.4.2_02
private : 2143 (ms)
private final : 2163 (ms)
private static final: 2434 (ms)
protected : 2714 (ms)
protected final : 2283 (ms)
protected static : 2604 (ms)
public : 2423 (ms)
1.3の頃に測定した結果と同じマシンであるのが好都合(マシン古すぎ;)。全部ほぼ平均的になってしまっていますよ?
今回はSUNのJ2SEのみの結果だが、IBMではもちろん実装が異なるため性能が変わる。性能向上となるコーディングをどうすればいいのか?というのは一概に言えないのに気づいた。HotspotやJITのおかげで過去の性能向上が通用するかしないかを毎回見極める必要があるということが言える。今、思い込んでいる速いと思っているコーディングは間違っているかもしれませんよ?

double-checked lockingに引っかかる

http://www-6.ibm.com/jp/developerworks/java/020726/j_j-dcl.html
2002年5月の記事。synchronizedをいかに少なくするかを検討していたところ、記述したらdouble-checked lockingイデオムはダメですとEclipseに怒られる。・゜・(ノ∀`)・゜・。
あきらめて、メソッド自体のsynchronizedは変更せず。