2011年6月20日月曜日

Effective Java からperformance 関連項目

以下、『Effective Java (2nd Edition)』 から、パフォーマンスに関係する項目。

:パフォーマンスに特に関係する項目
:パフォーマンスに割と関係する項目
:パフォーマンスに一部だけ関係する項目

Item 1: Consider static factory methods instead of constructors
オブジェクトの生成が抑えられるという static factory methods の利点について、instance-controlled class というキーワードで記述されている。Flyweight パターン(GoF)的に活用するとパフォーマンス向上に効果あり。

Item 5: Avoid creating unnecessary objects
「immutable なオブジェクトは常に再利用しよう」とか、「boxing / unboxing による暗黙のオブジェクト生成に気をつけよう」などといった注意喚起。

Item 6: Eliminate obsolete object references
メモリリーク対策として紹介されているが、オブジェクトへの参照を常に null out することは、無駄に内部品質(すなわちコーディングの生産性)を損なうバッド・プラクティスとされている。null 代入するなら、メモリリークを起こし易い場所に見当を付けて集中的に行うべき。

Item 7: Avoid finalizers
デストラクタ感覚で使うのは止めましょうという話だが、往々にして期待通りに動かないし、そもそも必要性からして疑わしい。さらに深刻なパフォーマンス劣化さえもたらしうるとの記述がある。

Item 9: Always override hashCode() when you override equals
極端な例だが、hashCode()で定数を返したりなんかすると、リニアなアクセス時間になって、本来 のHashXXX の パフォーマンスが得られないって話。

Item 15: Minimize mutability
クラスを定義する際には、できるだけ immutable にして行こうという、今ではかなり普及したプラクティス。パフォーマンスとの関連でいえば、無駄なオブジェクト生成を抑えられるという利点と、値が変わる度に新規インスタンスが必要になるという欠点の、両面があるので注意。

Item 48: Avoid float and double if exact answers are required
業務アプリのプログラマには常識的な話。ただ、あるデータ項目について、どの程度正確な値が求められているか、必ずしも自明ではない。BigDecimal で精度をとるかプリミティブ型でパフォーマンスをとるか、やはり要件によりけり。

Item 49: Prefer primitive types to boxed primitives
Integer や Long などを無自覚に使うと、暗黙の boxing / unboxing で深刻にパフォーマンスが落ちうると言う話。

Item 50: Avoid strings where other types are more appropriate
特にパフォーマンスへの言及は無いが、普通に考えればわかるとおり、本来それ専用の型定義で表現されるべきデータ構造を、下手に文字列なんかで扱ったりすると、内部品質にもパフォーマンスにも悪影響がある。

Item 51: Beware the performance of string concatenation
まあ常識。StringBuilder を使いましょうと。

Item 53: Prefer interfaces to reflection
普通のメソッド呼び出しより reflection の方が遅いという普通の話。

Item 54: Use native methods judiciously
昔と違って JVM が大幅に速くなった今では、JNI経由の native メソッド使用は、期待するほど効果がないという話。

Item 55: Optimize judiciously
「未熟な最適化は諸悪の根源」という Knuth の言葉など、今よりもメモリが小さくCPUが遅くてパフォーマンスが難問だった時代から受け継がれる先人の警句を引用して、やみくもなコード最適化/パフォーマンス・チューニングについて警告している。このブログでも書いてきた(これとかこれ)。

Item 57: Use exceptions only for exceptional conditions
Exception をループ境界の判定などの制御フローに使ったりするのは、本来の使い方から逸脱しているだけでなく、パフォーマンスにも悪影響がある。まあ、そこまでバカな事する人なんか見たことないけど。

Item 66: Synchronize access to shared mutable data
「アトミックなデータならば、パフォーマンス向上のための同期コード省略が可能」という迷信を批判。

Item 67: Avoid excessive synchronization
同期コードによる待ちが増えると、並行性の機会が奪われたりしてパフォーマンスが上がらないという普通の話。synchronize ブロックから alien method を呼ばないとか、synchronize ブロックを小さく留めるとかヒントが書かれているけど、まあ普通はそれほど簡単にいかないので、工夫のしどころではある。

Item 68: Prefer executors and tasks to threads
スレッドプールが標準APIで提供されているので活用すべし。

Item 69: Prefer concurrency utilities to wait and notify
高パフォーマンスな concurrent collection の紹介など、java.util.concurrent パッケージ活用のすすめ。

Item 71: Use lazy initialization judiciously
パフォーマンスに良かれと思って lazy initialization を書いても、大抵は逆効果だから止めておけと。どうしても必要なら、static field には lazy initialization class イディオム、instance field には double-check イディオムを使うこと。

Item 75: Consider using a custom serialized form
デフォルトのシリアライズ形式は、ロジカルなデータ形式に着目したカスタムのシリアライズより、パフォーマンスが悪い事が多い。

0 件のコメント:

コメントを投稿