「for 文 2.0」からのメタメッセージ
「 for 文 2.0(笑) 」を受けて、アリエル社内ではまた変な議論が繰り返されました。 事の発端は須崎さんがこの記事を紹介したところから始まります。JavaScriptの記事なのに、いきなり、まったく別の言語に話が及ぶのがアリエルらしいところです。
まずは、JavaScriptの
for(var i = 0, len = array.length; i < len; i++) { .... }
を受けて、井上さんが
Javaでもこの恰好悪いテクニックが有効だったりする事実が悲しい... (JITがあるから関係無いとIBMは言いますが)。
という発言です。彼は今、Javaのコードを書いているので、当然の発言でしょう。これに対して、生粋のJavaプログラマは
私は、1行の中に複数の操作(!?)を書かないようにしています。 でもそれは決してJVMの知性に対する不信のせいではなく、自分のコード読解能力が低 いためです... 自分の能力が環境よりも低いために文句も言わずに従順でいられる、ってのは幸せなのでしょうか、不幸せなのでしょうか。
少し謙遜が入っていますが、1行の中に複数の操作があると可読性が悪くなるという主張です。これに対して、井上さんは、
ちなみに、1行に複数書くことがポイントではなく、ローカル変数(上の例で言えばlenをわざわざ使う)を使う部分がポイントです。「Javaの鉄則」でも、Javaの高速化のための技術として紹介されていました。
不明なのが、この技術(参照が多い変数はいったんローカル変数に代入すべき)は、Javaがどれだけ進化しても変わらない鉄則なのか?、です。上の例で、array.lengthの部分がgetter系のメソッドの場合、Javaはループの終了チェックでいつも関数呼び出しをするのか、それとも(なんらかの魔法で)最適化が起きるのか、ここが分かりません。
さて、これで、最適化の話に変わっていきます。もう一人のJavaフリークは、
昔の記憶では、
int[] hoge; hoge.lengthはあまり遅くならない。
SomeObj hoge; hoge.length()見たいなのは、関数呼び出しのコストがかかり、最適化しにくいので遅くなる。
とのことです。昔の記憶というところに反応して井上さんはIBMの魔法により、すべてが都市伝説になるかもしれないということを紹介しています。
昔の記憶で何かを書くと、IBMが文句を言うかもしれません。
- http://www-06.ibm.com/jp/developerworks/java/030627/j_j-jtp04223.html
- http://www-06.ibm.com/jp/developerworks/java/051104/j_j-jtp09275.shtml
しかし、IBMの言うことは嘘っぽい(局所的には嘘ではなくても、それを積み上げた結果、Javaが速くなっているのかに疑問があります)。
Java Performance Tuning News (http://javanews.jp/javap/)でも、都合が良いデータには「当然でしょう」とクールに反応し、都合が悪いデータには「そんな(局所的な)パフォーマンスが重要でしょうか?」と受け流すのが常です。
ここで、皆さんお待ちかねのC++オタクの登場です。
malloc()と比較すれば、大抵のアロケーション実装は速いです。でも、それじゃC++と比較したことにはなりません。new演算子がmalloc()を直接使うような実装はまずないし、operator newをオーバーロードしてクラス毎に最適なアロケーションを提供するという手段もあります。
という前提を無視して「Javaの方が速いんだぜ、ふふん」とか言われてもなぁ。エスケープ分析は、本当に機能するならすごいけど(賢いJVMであれば、ってあたりが怪しい)。
以下、昔話。
.NETのCLRが上のページで言うところのコピー型コレクターを実装していて、JavaのGCよりもあらゆる面で高速だと主張する記事が、MSJだかMSDN MAGAZINEだかに載っていました。5年くらい前の話です。
と、.NETは5年も前からすごそうです。結局、何がいいのか結論が出ないまま、次のようにまとまりました。
- 大谷さんとアリエルのJavaプログラマたちは暖かい視線でJavaを見守っている
- 中山さん(C++オタク)はJavaを心底馬鹿にしている
- 井上さんはIBMをさらに馬鹿にしている
お後がよろしいようで。
- Category(s)
- 開発
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/dev/300cfor-6587-2-0300d304b3089306e30e130bf30e130c330bb30fc/tbping
[Java] 「.」のコストとfor文の最適化