Happy My Life

日常とか技術とか

Androidのプロファイリングツール「Traceview」

このTraceViewは、実は@androidzaurus氏に教えてもらうまでは、存在そのものを知らなかったツールだったりする。一言で言えばプロファイラ(Profiler)の事。プロファイラとは、関数単位で処理時間を測定してくれるツールを指す。公式ドキュメントはTraceview: A Graphical Log Viewer | Android Developersに。

プロファイラは、ちゃんと使えば結構有用なツールなので、どんな時にどんな風に使えばよいのかをざっと解説してみる。

最適化の手掛りとして

例えば、あるAndroidアプリが完成したとする。そのアプリは、バグらしきものは無いのだが、今イチ動作がキビキビせずに"もっさり"している、もしくは、ある条件で操作するとやたらと処理がかかってしまう、という問題を抱えていたとする。

そんな時に利用するのがプロファイラ。たとえば、先のもっさりしている中のプログムの処理時間を計測したとする。その計測結果を調査してみると、どの関数で、どれだけの処理がかかっているか数値となって見えてくる。

あとは、その問題の処理を、別スレッドで行うようにするなり、NDKを利用して高速化するなりして問題の対処にあたる。

ざっと言うとこんな感じ。最適化の手掛かりとして利用するのが本来の使い方。

勘で最適化するな

という話をすると、人によっては

「自分で作ったプログラムなんだから、どこで処理時間がかかっているか、そんなもの使わなくても見当つくよ」

って人がいるかもしれないが、

「チッ、チッ、チッ。それはどうかな?」

というのがおいらからの返答。

最適化というのは、バグが取れた状態で行うのはもちろん、計測などを行い原因を特定してから行うのが原則。もし、その勘が外れたらどうする? その最適化は徒労に終わってしまうか、もしくはもっと悪い結果になる事すらもありえる訳で。

ちなみに最適化する際に覚えておきたいのはバレートの法則。バレートの法則ってのは、別名80:20の法則とも言われている。今回の場合は「処理時間の8割は、プログラム全体の2割で消費されている」という事になる。なので、この2割を探すためにプロファイラを使うといっても過言ではない。

実際の使い方

では、実際に利用してみる。こんな感じに。

計測したい範囲でくくる

計測用のメソッドがあるので、それで囲む。こんな感じに

Debug.startMethodTracing(<ファイル名> );
 ...(計測したい処理)
Debug.stopMethodTracing();

<ファイル名>を処理毎に設定する事で、その箇所毎の計測結果が計測できる。ちなみに、この計測結果はSDカードに出力されるのでSDカードは必ず差しておくこと。

あと、SDカードに計測記録するので、AndroidManifest.xml




もお忘れなく。

アプリを実行

そしてアプリを実行する。デバッグモードでなく通常の実行でよいかと。ただし、先のDebug.startMethodTracing( <ファイル名> ) 〜 Debug.stopMethodTracing()でくくった範囲は、やたら実行に時間がかかってしまう。というのは、プロファイリング中は、SDカードに逐一データを記録しているためだと思われる。なので辛抱強く処理を待たなくてはいけないかもしれない。

そういう意味でも、計測する範囲は最初は広げすぎないように設定するとよい。じゃないと、計測そのものが終わらないというハメに陥ることに。

計測結果は、<ファイル名>.trace と “.trace"という拡張子(?)が付加されたファイルがSDカードに生成される。

計測結果をPCにコピー

次にSDカードに記録されている情報をPCにダウンロード。ターミナルから

% adb pull /sdcarc/<ファイル名>.trace .

で、カレントフォルダにダウンロードされる。

計測結果を閲覧する

あとは、計測結果をTraceViewで眺める。ターミナルから

% traceview <ファイル名>.trace

で閲覧できる。出力結果の一例はこんな感じ。

traceview

上のグラフは、視覚的に関数がどの時間、どの程度消費されているかを表したもの。

下の表は

incl %
Inclusive時間での全体に対する実行時間の割合
Inclusive
Inclusiveでかかった時間
Excl %
Exclusive時間での全体に対する実行時間の割合
Exclusive
Exclusiveでかかった時間
Calls+Rec
呼出回数
Time/Call
メソッドの実行時間

ちなみに、

Inclusive = 関数そのものでかかった時間 Exclusive = 関数そのものでかかった時間+関数呼出にかかった時間

らしい。

とにかく

バグって訳でないけど、一部にやたらと時間がかかる処理があって気になっている人は、このツールを利用使うといいかもしれない。

ただ、もっと便利にTraceViewを使う方法もあるみたい。それは今度。