[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 10148] Re: Effective Java 第 1 回議事録



(株)ネットジーンの村山です.

> この間のSun TECH DAYSで、「ローカル変数は最初の3つ(4つ?)に
> 宣言されたものへのアクセスが速い」なんてのがありましたが、

多分ですが,これはインタプリタ時代の遺物なのでは.

たしかlload_<n>とかdload_<n>とかは0,1,2,3までなんで,
nが0〜3までと4以上の時の速度が,インタプリタの場合は
異なる場合が多いでしょう.多分そのことを言ってるんじゃ
ないでしょうか.
#iconst_<i>は-1から5でしたっけ?定数を使うとき
#インタプリタでは-1から5の時と,-128から127の時と,
#それ以上の時とかで速度が変わったりするかもしれませんね.

もしそうならば,それこそJITがあれば関係ない話になります.
JVMの実装がそういう風にチューニングされてる可能性も
ないとはいえませんが...

> 意味的には、equals()の方がしっくりくるので、ただ「速いから」
> という理由では==は使いたくないですね。
#分かってる人には分かってるでしょうが,

しっくりくるとかどうとかではなく,==とequalsは「意味的に異なる」
というのが重要です.Stringに限らずインスタンスの「比較」には==と
equalsの二つがあり,この二つは意味的に異なります.で,Stringや
Longなどでは,意味的に異なるだけでなく実装レベルでも異なるわけです.
#下手な入門書ではこの辺がスッパリ抜けてる場合があるらしい.
#ちなみに実装レベルで同じ場合は,アクセサメソッドと同様に
#速度的にはほとんど差は出ないと思います.

意味的に異なるのでequalsを==に単純に「置き換える」ことは
一般にはできません.==が使いたければ,==で意味的に問題ない
ようなアルゴリズムを作らなければなりません.意味的に違うし
アルゴリズム的にも違うからこそJavaVMには最適化できず,その
処理はプログラマーに全面的に依存します.そういう意味では
これは実装依存の最適化というよりは,アルゴリズムレベルの
最適化でしょう.

そういう意味で,この最適化はソートアルゴリズムにクイック
ソートを使うかバブルソートを使うかの違いや,文字列を表現
するのにStringを使うかStringBufferを使うかの違いに似てると
思います.

ソートについてはオーダーが十分に小さければバブルソートで
十分です.オーダーがかなり大きいと前もって分かっている時に
バブルソートを使っているとすれば,やはり問題でしょう.
#最近はクイックソートがライブラリで用意されているので,
#例としてはよくないかもしれない.

文字列についても通常はStringで十分です.特にマルチスレッド
や分散環境では不変オブジェクトは都合が良いし,パフォーマンス
上も有利になる場合が多い.バグが出難いという点でもStringの方
が良いでしょう.

ただ,場合によってはStringの演算がボトルネックになる場合も
あり,その場合はStringBufferを使うことも検討すべきだというのは
ご存知の通り.しかし,これらは意味的に異なるものであり,一般的
には単純に置き換えることはできず,アルゴリズムの変更を要します.
#単純に置き換えても問題ない場合もあるが,その多くは
#バイトコード=コンパイラで暗黙に置き換えられると思う.
#この点も考慮すると,StringBufferを明示的に使わなければ
#ならない場合はさほど多くないはず.

...でいいんですかね?
なんせEffectiveJavaを読んでると,ささやかな自信なんて
根底から崩れていく気分になるもので.(^^;

>equals()と==をものによって使い分ける、
>というのも混乱しそうで避けたいです。
これは混乱するほど難しい代物でもないと思う.これが使い分け
られないようでは,StringとStringBufferの使い分けもできない
だろうし,アルゴリズムのことも理解できてないのでは.
#ちなみに,並列/分散アルゴリズムの難しさはこんな
#ものの比じゃない気がする.多分,だからこそEJBの
#開発は難しいのでは.どうでしょう,経験者の方.