どのメソッド (特にメイン スレッド上) の実行に 1 秒以上かかるかを調べようとしています。残念ながら、私は DDMS と traceview を使用していますが、提供されたデータの読み方がよくわかりません。長時間実行されるメソッドを見つける簡単な方法はありますか?
11 に答える
@Jake Whartonは、メソッドに注釈を付け、logcat でそれらのメソッドの実行時間を受け取ることができるHugoをリリースしました。
クラスを使用してSystemClock
、関数呼び出しの前後の時間の違いを把握できます。
long time_start = SystemClock.elapsedRealtime();
myFunction();
long time_end = SystemClock.elapsedRealtime();
long diff = (time_end - time_start) / 1000;
Log.i("mytag", "Time Difference: " + diff + " seconds");
ドキュメント: http://developer.android.com/reference/android/os/SystemClock.html
最も簡単な方法は、プログラムをデバッガーで実行することだと思います。ランダムな間隔で一時停止し、一時停止したときにプログラムが実行していたメソッドに注意してください。
遅い方法で一時停止する確率は、速い方法で一時停止するよりもはるかに高くなります。これは、一時停止したときにプログラムが実行していたメソッドが遅いメソッドであることを意味します。
詳細については、同様の質問に対する Mike Dunlavey の優れた回答を参照してください: https://stackoverflow.com/a/378024/1375762
関数の時間を計測する最速の方法はありませんが、正確かつ簡単に行うことができます。
正確にしたい場合は、マイクロ秒が最適な選択になると思います。
long startTime = System.nanoTime();
// ... the code being measured ...
long estimatedTime = System.nanoTime() - startTime;
実行中の Java 仮想マシンの高解像度タイム ソースの現在の値をナノ秒単位で返します。
したがって、これは必ずしもナノ秒の解像度ではなく、JVM から取得されます。予想どおり、関数の実行時間をテストする最も正確な方法です。
このメソッドはナノ秒の精度を提供しますが、必ずしもナノ秒の解像度 (つまり、値が変化する頻度) を提供するとは限りません。解像度が currentTimeMillis() の解像度と少なくとも同程度であることを除いて、保証はありません。
http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#nanoTime%28%29
また、ブレークポイントを使用してデバッガーを試すこともできます: http://docs.oracle.com/javase/7/docs/technotes/tools/windows/jdb.html
StrictModeを知っていますか? メインスレッドで重いものが実行されるたびにログに出力されます。レポートにはミリ秒単位の時間が含まれているため、UI スレッドをフリーズさせるコードを簡単に追跡できます。
メイン クラスのアイデアについては、junitと上記の提案のいずれかを使用して、Calendar.getTimeinMillis() または System.getNanoTime() を貼り付け、メソッド テストの最後で減算を実行できます。ミリ単位の時間はメソッドに存在しない可能性があるため、ナノ時間の方が適切です。上記の @Hugo メソッドまたはその他の必要なものを追加することもできます。
junit をメインと組み合わせますが、デバッグの理由からもテスト ケースを介してすべてを実行します。デバッガーは物事を遅くすることができるので、これはより正確です。
Junit の利点は、Java のあらゆるものに対して機能し、特定の回数の反復をテストしたり、アサーションを実行したりできることです。テストを完全に制御できるため、メソッド内で時間をテストすることもできます。インテルをはじめ、世界中の企業で使用されています。さらに、別のクラスから実行されるため、コードをクリーンに保ち、一連のロギングの必要性などを排除します。
コードは、テスト クラスで次のようになります。
//you could also use @Test(timeout=long)
@Test
public void testMethod()
{
YourClass test=new YourClass();
long s=System.getNanoTime();
//you could call your method directly here as well
assertEquals("name",50,test.yourMethod());
s=System.getNanoTime()-s;
}
開発環境などは何をお使いですか?
あなたが本当に探しているのはプロファイラーです。開発環境とテスト環境に適したものを探すと、プロファイラーの結果から、メソッドが呼び出される頻度と呼び出しにかかる時間がわかります。
組み込みの AndroidTimingLogger
クラスがあります。
https://developer.android.com/reference/android/util/TimingLogger