「.」のコストとfor文の最適化

「for 文 2.0」からのメタメッセージ
http://d.hatena.ne.jp/lethevert/20060628/p3

要約すると

for (int i=0; i < args.length; ++i) { //(1)

という書き方よりも

for (int i=0, len = args.length; i < len; ++i) { //(2)

という書き方の方が早いよという話で

うーんと,多分JIT導入以後のJavaにおいてはほぼ同じ.C++JavaScriptの人には理解し難いかもしれないけどね.*1

バイトコードレベルまでは明らかに異なるけれど,VMレベルで最適化されるので影響はかなり小さい.*2特にこれが形だけでもメソッド呼び出しになっている場合はバイトコードレベルでの最適化(というよりは「メソッド呼び出しの除去」かな)は禁止される.*3


問題があるとすればlengthフィールドがvolatile宣言されていた場合だろう.それがアルゴリズム上で必要不可欠な場合はともかく,そうでないならば明らかに(2)の書き方にすべきだ.通常はループ部分は複数のループ間にまたがったグローバルな最適化が行われるものだが,volatile変数やsynchronizedメソッドはそういう最適化を阻害してしまう.*4

これはvolatile変数やsynchronizedメソッドが,ある種の制約を意味する命令であり,これにより幾つかの最適化が禁止されることによる.このような最適化に対する制約はvolatile変数やsynchronizedメソッドの本質部分と言って良い.volatile変数/synchronizedドメソッドにおいては,(1)から(2)の書き方に変更するのは見た目上は大差ないように見えるかもしれないが,同期処理とそれに伴うアルゴリズムが変更されていることを理解しなければならない.これを理解していないプログラマは半人前だ.*5

*1:Javaの人でも理解してない人の方が多いのは問題だよなあ...

*2:JavaScriptC++だと「VMレベルの最適化」という発想がないので,議論からスッパリと抜け落ちることがよくある.

*3:そうしないと開発時に非常に厄介な問題を抱え込むことになる.下手するとDLL地獄みたいになってしまう.またこれがあるから「外部仕様を変更せずに,実装を改良する」ことも容易に行える.

*4:CやC++にはそういう最適化がほとんどないし,そもそもマルチスレッド自体があまり使われていないので,これが最適化の阻害要因だという意識も薄いだろう.

*5:しかもこの『半人前』のプログラマが,おそらくJavaプログラマの大半を占めるというのだから浮かばれない.

「新幹線で街は栄えない」 全駅を乗り降りした自称オタクの銀行マンが講演

http://www.bnn-s.com/bnn/bnnMain?news_genre=2&news_cd=220011027965

「新幹線は人口を流出させる効果が非常に大きい。終着駅効果があるとか、新幹線で街が栄えるという主張には何の根拠もない」「新幹線が通ると観光客が減るのが全国的な傾向。新幹線が通ると風情が壊れ、すぐに帰ろうという気持ちになるから」

まあ,そりゃそうだろうねえ.