Androidとリフレクション(HT-03A編)
ちょっと無茶かなと思いながらも、先日のテストをdocomo HT-03A/HTC Magic(Android 1.6)でも実行してみることにした。
しかし、そのままのコードでは一つのテストタスクが終了する前にANR※となってしまい計測にならないので、テストロジックを別スレッドで実行し、結果を文字列で戻すようにコードを変更することにした。
- ReflectionTest (別スレッド版)
new Thread(new Runnable() {
@Override
public void run() {
Task tasks = new Task {
new MethodCallTask(),
new FieldCallTask(),
new ReflectionTask(),
new ReflectionTaskWithSearchSetter()
new ReflectionFieldTask(),
new ReflectionFieldTaskWithSearchField(),
};
try {
Measure measure = new Measure();
measure.setCount( 100000 ); // 1タスクを10万回実行する。
measure.run( tasks );
final String result = measure.result.toString();
ReflectionTest.this.runOnUiThread(new Runnable() {
@Override
public void run() {
txt.setText(result);
}
});
} catch ( Throwable e ) {
e.printStackTrace();
}
}
}).start();
#必殺のRunnable二重実装。この辺もっと見通しよく実装できるようになればなぁ。Javaじゃ無理だなぁ。
- 実行結果
コードが変更になったため、念のためEmulator、Nexus oneでも追試を実施している。
タスク | HT-03A | Emulator | Nexus one | JavaSE6 |
---|---|---|---|---|
メソッド呼び出し | 150 msec | 243msec | 37msec | 1msec未満 |
フィールドアクセス | 114msec | 300msec | 27msec | 1msec未満 |
リフレクション-メソッド(検索時間を含まず) | 3540msec | 2395msec | 488msec | 43msec |
リフレクション-メソッド(検索時間を含む ) | 11597msec | 7823msec | 2000msec | 193msec |
リフレクション-フィールド(検索時間を含まず) | 1065msec | 790msec | 164msec | 67msec |
リフレクション-フィールド(検索時間を含む ) | 6492msec | 3097msec | 703msec | 202msec |
コードを変えた影響はあるようで全ての環境において若干だが結果が変わっている。UIスレッド外で処理を行うようにしたため実行スレッドの優先度が下がることによる影響だろうか。エミュレータはスレッドの切替えには特に弱く、如実に影響が出ている。
結論として、やはりHT-03Aには荷が重かった。リフレクションを使用した結果はPC上で動かしたエミュレータにも劣っており、最も重いテスト(リフレクション-メソッド-検索時間含む)での経過時間は1万msecを超えてしまっている。これではちょっと厳しいだろう。
- ここまでのAndroidのリフレクション戦略
Javaがそうだったようにパフォーマンス戦略は1年も経てば違うものになっている可能性があるため、努々これが鉄則などとは思わないことだ。
逆に「まず計測してみるべし」というのはどんなプラットホームでも鉄則だ。
※Application Not Responding. Androidがアプリケーションの無反応を検出してすることをいい、SDKと同じコードであればUIスレッドで5秒の遅延はANRと判断される。