javaでプログラムを作成したのですが、これの処理時間を計測したいと考えています
実行してから終了するまでの時間の計測方法はわかるのですが
より正確に処理時間を把握するために複数回実行してその平均を
とりたいと考えています
プログラムの実行を指定回数自動で行い出力結果を得る
方法はありますか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答3件
0
java プロファイラ ツール
で google 検索すると、CPU 使用率の高いメソッドをみつけることなどができます。
検索結果からの紹介
- Java VisualVM でパフォーマンスのボトルネックを突き止める
http://www.techscore.com/blog/2017/12/11/identifying_performance_bottlenecks_with_jvisualvm/
- Java 解析ツール比較ガイド
投稿2018/12/24 07:08
総合スコア22328
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
あまりいろいろ気にせず素朴にやるなら自分でループを書いて実行速度の平均を計算するのが手っ取り早い気がしますが、その結果はタイマーの精度やJVMの最適化(Just-In-Time compilerによるネイティブコードへの自動コンパイルなど)やガーベージコレクターによる実行時間変動などにより大きく影響を受けますのでそうしたものに配慮する計測は意外に面倒だと思います。
自分が使ったことがないものを紹介するのはアレですがOpenJDKプロジェクトで公開されている性能計測用のライブラリーがあるとのことです。
http://openjdk.java.net/projects/code-tools/jmh/
これは単に「指定回数ループさせ実行時間の平均を取る」といった単純なものではなく指定した処理の1秒あたりの実行回数がどの程度なのかを誤差なども含めて自動計測してくれるようです。
上のページに使い方が書いてあるはずですが検索すると日本語での使用例の紹介なども見つかります。
https://blog.y-yuki.net/entry/2016/09/07/010000
なお、自分はそうまで真剣に性能測定に取り組んだことがなく大抵は「何回かあらかじめループさせてJITがコンパイルしてくれただろうことを期待した上でN回ループしたときの平均と標準偏差(時にGCの回数なども)を何回か計算し結果を目視で吟味する」といった程度のことしかしません。(アマチュアなもので...)
きちんとした測定とは言えませんがそれでも結構なコード量になります。前述のJMHを利用した方が確実だろうと思います。
java
1import java.lang.management.ManagementFactory; 2import java.lang.management.GarbageCollectorMXBean; 3import java.util.stream.Stream; 4import java.util.stream.Collectors; 5 6// 測定対象1: プリミティブ型を用いた累加処理 7class ProcPri implements Runnable { 8 int result; 9 10 public void run() { 11 int sum = 0; 12 for (int i = 0; i < 1_000_000; i++) { 13 sum += i; 14 } 15 result = sum; 16 } 17} 18 19// 測定対象2: ラッパータイプを用いた累加処理 20class ProcBox implements Runnable { 21 Integer result; 22 23 public void run() { 24 Integer sum = 0; 25 for (int i = 0; i < 1_000_000; i++) { 26 sum += i; 27 } 28 result = sum; 29 } 30} 31 32// 測定用のコード 33class ETM { 34 public static void main(String[] args) { 35 Runnable procPri = new ProcPri(); 36 Runnable procBox = new ProcBox(); 37 38 for (int i = 0; i < 10; i++) { 39 etm("pri", procPri, 20); 40 etm("box", procBox, 20); 41 } 42 } 43 44 static void etm(String title, Runnable runnable, int n) { 45 var gcs = ManagementFactory.getGarbageCollectorMXBeans().stream() 46 .filter(GarbageCollectorMXBean::isValid) 47 .collect(Collectors.toMap(identity(), GarbageCollectorMXBean::getCollectionCount)); 48 49 double s1 = 0, s2 = 0; 50 51 for (int i = 0; i < n; i++) { 52 long t = -System.nanoTime(); 53 runnable.run(); 54 t += System.nanoTime(); 55 s1 += t / 1E9; 56 s2 += t * t /1E18; // すみません、1E18で割るのを忘れてたコードを載せてました。 57 } 58 59 double mean = s1 / n; 60 double std = Math.sqrt(s2 / n - mean * mean); 61 62 System.out.format("%s: mean %.9f std %.9f gc", title, mean, std); 63 64 for (var gcBean: ManagementFactory.getGarbageCollectorMXBeans()) { 65 if (gcBean.isValid()) { 66 System.out.format(" %d", gcBean.getCollectionCount() - gcs.get(gcBean)); 67 } 68 } 69 System.out.println(); 70 } 71}
===>
bash
1$ java ETM 2pri: mean 0.000450753 std 0.000512748 gc 0 0 <= 初回はかなり時間がかかる。偏差も大きい 3box: mean 0.004843579 std 0.002445166 gc 2 0 4pri: mean 0.000279995 std 0.000000470 gc 0 0 <= 2回目はかなり偏差が小さくなる 5box: mean 0.002278036 std 0.000452674 gc 2 0 6pri: mean 0.000272811 std 0.000000488 gc 0 0 7box: mean 0.003139957 std 0.001825407 gc 2 0 <= しかしGCが起きるようなものはやはり偏差大 8pri: mean 0.000275036 std 0.000007335 gc 0 0 9box: mean 0.002275702 std 0.000455196 gc 2 0 10pri: mean 0.000282001 std 0.000020618 gc 0 0 11box: mean 0.003770276 std 0.002332905 gc 1 0 12...
投稿2018/12/22 02:14
編集2018/12/22 03:20総合スコア18404
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。