M12i.

学術書・マンガ・アニメ・映画の消費活動とプログラミングについて

ProGuardマニュアル(5) 最適化オプション

原文は、ProGuard Manual”(Eric Lafortune)です(2011年3月29日取得)。

イントロダクションと索引はこちら

*****************************

最適化オプション

-dontoptimize

入力クラスファイルを最適化しないよう指定します。デフォルトでは最適化機能が有効になっており、すべてのメソッドがバイトコードレベルで最適化されます。

-optimizations optimization_filter

最適化の有効無効をよりきめ細かく指定します。最適化処理においてのみ有効なオプションです。

-optimizationpasses n

最適化の処理を何回実施するか指定します。デフォルトでは、最適化は1回だけ実施されます。複数回実施することで処理結果の向上を期待できます。最適化を実施しても変化がない場合、最適化処理は終了します。最適化処理においてのみ有効なオプションです。

-assumenosideeffects class_specification

(値を返す以外の)副作用のないメソッドを指定します。最適化のステップでは、ProGuardは返値が利用されていないと判断できるメソッドの呼び出しを削除しれます。ProGuardは入力クラスファイルのコードを解析し、そのようなメソッドを自動で発見します。しかしこの解析はライブラリコードに対しては実施されません。このため-assumenosideeffects オプションが活きていきます。例えば、無駄なメソッド呼び出しをすこしでも減らすため、System.currentTimeMillis() メソッドをこのオプションを使用して指定するといったことができます。ProGuardはこのオプションを、指定されたメソッドの呼び出し階層のすべてにわたって適用することに注意してください。最適化処理においてのみ有効なオプションです。一般的に、憶測でことをなすのは危険なことです。(訳者:このオプションの使い方を誤ると)容易にコードを破壊できてしまうのです。自身が何をしているかを理解している場合にのみ、このオプションを使用してください。

-allowaccessmodification

最適化処理の過程で、クラスとクラス・メンバーのアクセス修飾子をより広いアクセスを提供する修飾子に変更可能であるかどうかを指定します。このオプションによって、最適化ステップの成果をより良いものにすることができます。例えば、publicな設定メソッド(getterメソッド)をインライン化するとき、その設定メソッドによりアクセスされるフィールドもまたpublicに変更する必要があることがあります。本来Javaバイナリ互換性仕様ではこのような変更は不要なのですが(Java言語仕様、第2版第13章4節6項を参照)、いくつかのJVM実装ではこの方法をとらないと問題が発生します。最適化処理(と-repackageclasses オプションをともなう難読化処理過程)においてのみ有効なオプションです。

使用すべきでないケース:ライブラリとして使用されるコードを処理する場合、このオプションは使用できない可能性があります。このオプションによって、APIのなかで、publicアクセスとして設計されていないクラスやクラス・メンバーまでもがpublicに変更されてしまう可能性があるためです。

-mergeinterfacesaggressively

仮に実装クラスが当該のインターフェースのメソッドすべてを実装していない場合でも、インターフェース同士をマージできるよう指定します。このオプションは、クラスの総数を削減することにより、出力ファイルのサイズを低減するものです。Java言語としては許されないことなのですが(Java言語仕様、第2版第8章1節4項を参照)、Javaバイナリ互換性仕様はこのような構造を許しています(Java言語仕様、第2版第13章5節3項を参照)。

使用すべきでないケース:このオプションを設定することにより、いくつかのJVM実装上ではコード実行のパフォーマンスが低下します。これは先進的なJITコンパイラ実装が、より多くのインターフェースとより少数の実装クラスを処理するのに適している傾向があるためです。さらには、いくつかのJVM実装では、このマージ処理を行ったコードを実行できない可能性もあります。

顕著なケース:

  • サンマイクロシステムズのJRE バージョン1.3では、1つのクラスに256より多くのMirandaメソッド(実装をともなわないインターフェース・メソッド*1)が存在したとき、InternalErrorを発生させます。

******************************

ProGuardマニュアル(6)につづく。

*1:訳者: Mirandaメソッドは、実装をともなわないメソッドというより、実装されていないために実行環境──JVMが便宜的に提供するメソッドのことを指すのが本来のようです。[http://lists.xcf.berkeley.edu/lists/advanced-java/2001-September/017523.html:title=こちらのメーリングリスト]では、「『もしクラスがメソッドを提供できないのなら、かわりにコンパイラが提供する』という文面が、『もしあなたが弁護士を立てることができないのなら、法廷がかわりに立てる』というそれ──米国において「ミランダ権」と呼ばれるもの──にとても似ているから」とあるのですが、いまいちその「似ている」というのが理解しきれないところではあります。