web-dev-qa-db-ja.com

Javaでメソッドの実行を計時する方法は?

メソッドの実行時間はどのようにしてわかりますか?タスクにかかる時間などを計るためのTimerユーティリティクラスはありますか?

Googleでの検索のほとんどは、スレッドとタスクをスケジュールするタイマーの結果を返しますが、これは私が望んでいることではありません。

752
Ogre Psalm33

いつも昔ながらの方法があります。

long startTime = System.nanoTime();
methodToTime();
long endTime = System.nanoTime();

long duration = (endTime - startTime);  //divide by 1000000 to get milliseconds.
1085
Diastrophism

私は簡単な答えで行きます。私のために働きます。

long startTime = System.currentTimeMillis();

doReallyLongThing();

long endTime = System.currentTimeMillis();

System.out.println("That took " + (endTime - startTime) + " milliseconds");

それはかなりうまくいきます。解像度は明らかにミリ秒にすぎません、あなたはSystem.nanoTime()でよりよくすることができます。両方にいくつかの制限があります(オペレーティングシステムのスケジュールスライスなど)が、これはかなりうまくいきます。

2、3回の実行で平均して(より良いほど)、あなたはまともな考えを得るでしょう。

173
MBCook

みんなおいでよ!誰も グアバ それをする方法に言及していません(これは間違いなく素晴らしいです)。

import com.google.common.base.Stopwatch;

Stopwatch timer = Stopwatch.createStarted();
//method invocation
LOG.info("Method took: " + timer.stop());

いいことに、Stopwatch.toString()は測定のための時間単位を選択するのに適しています。すなわち値が小さい場合は38 nsを出力し、長い場合は5 m 3 sを表示します。

さらに良い:

Stopwatch timer = Stopwatch.createUnstarted();
for (...) {
   timer.start();
   methodToTrackTimeFor();
   timer.stop();
   methodNotToTrackTimeFor();
}
LOG.info("Method took: " + timer);

注:Google GuavaにはJava 1.6以降が必要です

161

Java 8の新しいAPIから Instant および Duration を使用して、

Instant start = Instant.now();
Thread.sleep(5000);
Instant end = Instant.now();
System.out.println(Duration.between(start, end));

出力

PT5S
123
Sufiyan Ghori

プロファイラー(JProfiler、Netbeansプロファイラー、ビジュアルVM、Eclipseプロファイラーなど)を使用してください。あなたは最も正確な結果を得るでしょう、そして最も邪魔になりません。プロファイリングには組み込みのJVMメカニズムを使用しているため、スタックトレース、実行パス、および必要に応じてより包括的な結果などの追加情報も得られます。

完全に統合されたプロファイラーを使うとき、メソッドをプロファイリングするのは些細なことです。右クリックし、[プロファイラ] - > [ルートメソッドに追加]をクリックします。次に、テストランやデバッガを実行しているときと同じようにプロファイラを実行します。

84
James Schek

1つの場所にすべての可能な方法をまとめました。

日付

Date startDate = Calendar.getInstance().getTime();
long d_StartTime = new Date().getTime();
Thread.sleep(1000 * 4);
Date endDate = Calendar.getInstance().getTime();
long d_endTime = new Date().getTime();
System.out.format("StartDate : %s, EndDate : %s \n", startDate, endDate);
System.out.format("Milli = %s, ( D_Start : %s, D_End : %s ) \n", (d_endTime - d_StartTime),d_StartTime, d_endTime);

System. currentTimeMillis()

long startTime = System.currentTimeMillis();
Thread.sleep(1000 * 4);
long endTime = System.currentTimeMillis();
long duration = (endTime - startTime);  
System.out.format("Milli = %s, ( S_Start : %s, S_End : %s ) \n", duration, startTime, endTime );
System.out.println("Human-Readable format : "+millisToShortDHMS( duration ) );

人間が読むことができる 形式

public static String millisToShortDHMS(long duration) {
    String res = "";    // Java.util.concurrent.TimeUnit;
    long days       = TimeUnit.MILLISECONDS.toDays(duration);
    long hours      = TimeUnit.MILLISECONDS.toHours(duration) -
                      TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
    long minutes    = TimeUnit.MILLISECONDS.toMinutes(duration) -
                      TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
    long seconds    = TimeUnit.MILLISECONDS.toSeconds(duration) -
                      TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
    long millis     = TimeUnit.MILLISECONDS.toMillis(duration) - 
                      TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(duration));

    if (days == 0)      res = String.format("%02d:%02d:%02d.%04d", hours, minutes, seconds, millis);
    else                res = String.format("%dd %02d:%02d:%02d.%04d", days, hours, minutes, seconds, millis);
    return res;
}

グアバ:Google ストップウォッチ _ jar _ «ストップウォッチの目的は、経過時間をナノ秒単位で測定することです。

com.google.common.base.Stopwatch g_SW = Stopwatch.createUnstarted();
g_SW.start();
Thread.sleep(1000 * 4);
g_SW.stop();
System.out.println("Google StopWatch  : "+g_SW);

Apache Commons Lang_ jar _ « StopWatchはタイミングに便利なAPIを提供します。

org.Apache.commons.lang3.time.StopWatch sw = new StopWatch();
sw.start();     
Thread.sleep(1000 * 4);     
sw.stop();
System.out.println("Apache StopWatch  : "+ millisToShortDHMS(sw.getTime()) );

_ joda _ - TIME

public static void jodaTime() throws InterruptedException, ParseException{
    Java.text.SimpleDateFormat ms_SDF = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
    String start = ms_SDF.format( new Date() ); // Java.util.Date

    Thread.sleep(10000);

    String end = ms_SDF.format( new Date() );       
    System.out.println("Start:"+start+"\t Stop:"+end);

    Date date_1 = ms_SDF.parse(start);
    Date date_2 = ms_SDF.parse(end);        
    Interval interval = new org.joda.time.Interval( date_1.getTime(), date_2.getTime() );
    Period period = interval.toPeriod(); //org.joda.time.Period

    System.out.format("%dY/%dM/%dD, %02d:%02d:%02d.%04d \n", 
        period.getYears(), period.getMonths(), period.getDays(),
        period.getHours(), period.getMinutes(), period.getSeconds(), period.getMillis());
}

Java 8からのJava日時API «A Duration objectは、2つの Instant オブジェクトの間の期間を表します。

Instant start = Java.time.Instant.now();
    Thread.sleep(1000);
Instant end = Java.time.Instant.now();
Duration between = Java.time.Duration.between(start, end);
System.out.println( between ); // PT1.001S
System.out.format("%dD, %02d:%02d:%02d.%04d \n", between.toDays(),
        between.toHours(), between.toMinutes(), between.getSeconds(), between.toMillis()); // 0D, 00:00:01.1001 

Spring Framework Javaで経過時間を測定するための StopWatch ユーティリティクラス。

StopWatch sw = new org.springframework.util.StopWatch();
sw.start("Method-1"); // Start a named task
    Thread.sleep(500);
sw.stop();

sw.start("Method-2");
    Thread.sleep(300);
sw.stop();

sw.start("Method-3");
    Thread.sleep(200);
sw.stop();

System.out.println("Total time in milliseconds for all tasks :\n"+sw.getTotalTimeMillis());
System.out.println("Table describing all tasks performed :\n"+sw.prettyPrint());

System.out.format("Time taken by the last task : [%s]:[%d]", 
        sw.getLastTaskName(),sw.getLastTaskTimeMillis());

System.out.println("\n Array of the data for tasks performed « Task Name: Time Taken");
TaskInfo[] listofTasks = sw.getTaskInfo();
for (TaskInfo task : listofTasks) {
    System.out.format("[%s]:[%d]\n", 
            task.getTaskName(), task.getTimeMillis());
}

出力:

Total time in milliseconds for all tasks :
999
Table describing all tasks performed :
StopWatch '': running time (millis) = 999
-----------------------------------------
ms     %     Task name
-----------------------------------------
00500  050%  Method-1
00299  030%  Method-2
00200  020%  Method-3

Time taken by the last task : [Method-3]:[200]
 Array of the data for tasks performed « Task Name: Time Taken
[Method-1]:[500]
[Method-2]:[299]
[Method-3]:[200]
73
Yash

これはおそらくあなたが私に言わせたかったことではありませんが、これはAOPの良い使い方です。あなたのメソッドの周囲にプロキシインターセプターを作り、そこでタイミングを決めます。

残念ながら、AOPの内容、理由、方法はこの回答の範囲を超えていますが、それが私のやり方です。

編集: ここにリンクがあります あなたが熱心であれば、始めるためのSpring AOPへ。これは、IiveがJavaに遭遇するAOPの最もアクセスしやすい実装です。

また、他のみんなの非常に単純な提案を考えると、AOPはあなたがあなたのコードに侵入するタイミングのようなものが欲しくないときのためのものであることを付け加えるべきです。しかし多くの場合、そのような単純で簡単なアプローチは問題ありません。

36
skaffman

System.currentTimeMillis(); ISあなたのアルゴリズムの性能を測定するための良い方法ではありません。これは、ユーザーがコンピューターの画面を見ているときの合計時間を測定します。バックグラウンドでコンピュータ上で実行されている他のすべてのものによって消費された時間も含まれます。あなたのワークステーションでたくさんのプログラムが動いている場合、これは大きな違いを生む可能性があります。

適切な方法はJava.lang.managementパッケージを使うことです。

http://nadeausoftware.com/articles/2008/03/Java_tip_how_get_cpu_and_user_time_benchmarking Webサイトから:

  • 「ユーザー時間」は、アプリケーション独自のコードの実行に費やされた時間です。
  • 「システム時間」は、アプリケーションの代わりにOSコードを実行するのに費やした時間です(I/Oなど)。

getCpuTime()メソッドはあなたにそれらの合計を与える:

import Java.lang.management.ManagementFactory;
import Java.lang.management.ThreadMXBean;

public class CPUUtils {

    /** Get CPU time in nanoseconds. */
    public static long getCpuTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            bean.getCurrentThreadCpuTime( ) : 0L;
    }

    /** Get user time in nanoseconds. */
    public static long getUserTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            bean.getCurrentThreadUserTime( ) : 0L;
    }

    /** Get system time in nanoseconds. */
    public static long getSystemTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            (bean.getCurrentThreadCpuTime( ) - bean.getCurrentThreadUserTime( )) : 0L;
    }

}
34
TondaCZE

Java 8では、すべての通常の メソッド で次のようなこともできます。

Object returnValue = TimeIt.printTime(() -> methodeWithReturnValue());
//do stuff with your returnValue

timeItのように:

public class TimeIt {

public static <T> T printTime(Callable<T> task) {
    T call = null;
    try {
        long startTime = System.currentTimeMillis();
        call = task.call();
        System.out.print((System.currentTimeMillis() - startTime) / 1000d + "s");
    } catch (Exception e) {
        //...
    }
    return call;
}
}

この方法を使用すると、コードを壊すことなくコード内のどこにでも簡単に時間を測定できます。この簡単な例では、時間を表示するだけです。 TimeItにSwitchを追加してもよいですか。 DebugModeか何かで時間を表示するだけです。

関数 で作業している場合は、次のようにすることができます。

Function<Integer, Integer> yourFunction= (n) -> {
        return IntStream.range(0, n).reduce(0, (a, b) -> a + b);
    };

Integer returnValue = TimeIt.printTime2(yourFunction).apply(10000);
//do stuff with your returnValue

public static <T, R> Function<T, R> printTime2(Function<T, R> task) {
    return (t) -> {
        long startTime = System.currentTimeMillis();
        R apply = task.apply(t);
        System.out.print((System.currentTimeMillis() - startTime) / 1000d
                + "s");
        return apply;
    };
}
23
Stefan

また、時間を測定するためにApache commonsのStopWatchクラスを使用することもできます。

サンプルコード

org.Apache.commons.lang.time.StopWatch sw = new org.Apache.commons.lang.time.StopWatch();

System.out.println("getEventFilterTreeData :: Start Time : " + sw.getTime());
sw.start();

// Method execution code

sw.stop();
System.out.println("getEventFilterTreeData :: End Time : " + sw.getTime());
16
Narayan

ツーリングを使用せず、実行時間の短いメソッドを計時したい場合は、ちょっとした工夫をしてください。したがって、System.nanoTimeへの呼び出しの時間など、System.nanoTimeの精度も結果に大きな影響を与えません。

    int runs = 0, runsPerRound = 10;
    long begin = System.nanoTime(), end;
    do {
        for (int i=0; i<runsPerRound; ++i) timedMethod();
        end = System.nanoTime();
        runs += runsPerRound;
        runsPerRound *= 2;
    } while (runs < Integer.MAX_VALUE / 2 && 1000000000L > end - begin);
    System.out.println("Time for timedMethod() is " + 
        0.000000001 * (end-begin) / runs + " seconds");

もちろん、ウォールクロックの使用に関する注意点が適用されます。JITコンパイルの影響、マルチスレッド/プロセスなど。したがって、最初にメソッドたくさんを最初に実行する必要があります。その作業を行い、次にこのテストを複数回繰り返して、最も短い実行時間をかけます。

14

この目的のためにAspectJとJavaのアノテーションを使っています。メソッドの実行時間を知る必要がある場合は、単純に注釈を付けます。より高度なバージョンでは、実行時に有効または無効にできる独自のログレベルを使用できます。

public @interface Trace {
  boolean showParameters();
}

@Aspect
public class TraceAspect {
  [...]
  @Around("tracePointcut() && @annotation(trace) && !within(TraceAspect)")
  public Object traceAdvice ( ProceedingJintPoint jP, Trace trace ) {

    Object result;
    // initilize timer

    try { 
      result = jp.procced();
    } finally { 
      // calculate execution time 
    }

    return result;
  }
  [...]
}
12
murdochjohn

本当に良いコードです。

http://www.rgagnon.com/javadetails/Java-0585.html

import Java.util.concurrent.TimeUnit;

long startTime = System.currentTimeMillis();
........
........
........
long finishTime = System.currentTimeMillis();

String diff = millisToShortDHMS(finishTime - startTime);


  /**
   * converts time (in milliseconds) to human-readable format
   *  "<dd:>hh:mm:ss"
   */
  public static String millisToShortDHMS(long duration) {
    String res = "";
    long days  = TimeUnit.MILLISECONDS.toDays(duration);
    long hours = TimeUnit.MILLISECONDS.toHours(duration)
                   - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
    long minutes = TimeUnit.MILLISECONDS.toMinutes(duration)
                     - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
    long seconds = TimeUnit.MILLISECONDS.toSeconds(duration)
                   - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
    if (days == 0) {
      res = String.format("%02d:%02d:%02d", hours, minutes, seconds);
    }
    else {
      res = String.format("%dd%02d:%02d:%02d", days, hours, minutes, seconds);
    }
    return res;
  }
10
iceberg

JEP 230:マイクロベンチマークスイート

参考までに、 JEP 230:Microbenchmark SuiteOpenJDK のプロジェクトである。

JDKソースコードに基本的な一連のマイクロベンチマークを追加し、開発者が既存のマイクロベンチマークを実行して新しいものを作成するのを簡単にします。

この機能は Java 12 に入っています。

Javaマイクロベンチマークハーネス(JMH)

以前のバージョンのJavaについては、JEP 230の基になっている Java Microbenchmark Harness(JMH) プロジェクトを見てください。

9
Basil Bourque

あなたは Perf4j を使うことができます。とてもかっこいいユーティリティ。使い方は簡単

String watchTag = "target.SomeMethod";
StopWatch stopWatch = new LoggingStopWatch(watchTag);
Result result = null; // Result is a type of a return value of a method
try {
    result = target.SomeMethod();
    stopWatch.stop(watchTag + ".success");
} catch (Exception e) {
    stopWatch.stop(watchTag + ".fail", "Exception was " + e);
    throw e; 
}

詳しい情報は 開発者ガイド にあります。

編集: プロジェクトは死んでいるようだ

7
mergenchik
new Timer(""){{
    // code to time 
}}.timeMe();



public class Timer {

    private final String timerName;
    private long started;

    public Timer(String timerName) {
        this.timerName = timerName;
        this.started = System.currentTimeMillis();
    }

    public void timeMe() {
        System.out.println(
        String.format("Execution of '%s' takes %dms.", 
                timerName, 
                started-System.currentTimeMillis()));
    }

}
7
Maciek Kreft

AOP/AspectJと jcabi-aspect@Loggable アノテーションを使うと、簡単でコンパクトにできます。

@Loggable(Loggable.DEBUG)
public String getSomeResult() {
  // return some value
}

このメソッドを呼び出すたびに、DEBUGロギングレベルでSLF4Jロギング機能に送信されます。そしてすべてのログメッセージは実行時間を含みます。

6
yegor256

私は基本的にこれの変形をしますが、ホットスポットのコンパイルがどのように機能するかを考えると、正確な結果を得たいならあなたは最初の2、3の測定を捨ててそしてあなたが実際の世界で読む方法を使うことを確かめる必要があります。

JITがそれをコンパイルすることにした場合、あなたの数字は大きく異なります。気をつけて

6
luke

それにはいくつかの方法があります。私は通常、このようなものを使うことに頼ります。

long start = System.currentTimeMillis();
// ... do something ...
long end = System.currentTimeMillis();

system.nanoTime()でも同じことが言えます。

物事のベンチマーク面でもっと何かのためにもこれがあるようです: http://jetm.void.fm/ それを試したことがない。

5
Horst Gutmann

Springは、JavaDocに従って、 org.springframework.util.StopWatch というユーティリティクラスを提供しています。

単純なストップウォッチ。複数のタスクのタイミングを考慮し、合計実行時間と各名前付きタスクの実行時間を公開します。

使用法:

StopWatch stopWatch = new StopWatch("Performance Test Result");

stopWatch.start("Method 1");
doSomething1();//method to test
stopWatch.stop();

stopWatch.start("Method 2");
doSomething2();//method to test
stopWatch.stop();

System.out.println(stopWatch.prettyPrint());

出力:

StopWatch 'Performance Test Result': running time (millis) = 12829
-----------------------------------------
ms     %     Task name
-----------------------------------------
11907  036%  Method 1
00922  064%  Method 2

アスペクトあり:

@Around("execution(* my.package..*.*(..))")
public Object logTime(ProceedingJoinPoint joinPoint) throws Throwable {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    Object retVal = joinPoint.proceed();
    stopWatch.stop();
    log.info(" execution time: " + stopWatch.getTotalTimeMillis() + " ms");
    return retVal;
}
4
Sunil Manheri

メソッドの実行時間を読みやすい形式で出力するメソッドを書きました。たとえば、100万の階乗を計算するには、約9分かかります。そのため、実行時間は次のように出力されます。

Execution Time: 9 Minutes, 36 Seconds, 237 MicroSeconds, 806193 NanoSeconds

コードはこちらです。

public class series
{
    public static void main(String[] args)
    {
        long startTime = System.nanoTime();

        long n = 10_00_000;
        printFactorial(n);

        long endTime = System.nanoTime();
        printExecutionTime(startTime, endTime);

    }

    public static void printExecutionTime(long startTime, long endTime)
    {
        long time_ns = endTime - startTime;
        long time_ms = TimeUnit.NANOSECONDS.toMillis(time_ns);
        long time_sec = TimeUnit.NANOSECONDS.toSeconds(time_ns);
        long time_min = TimeUnit.NANOSECONDS.toMinutes(time_ns);
        long time_hour = TimeUnit.NANOSECONDS.toHours(time_ns);

        System.out.print("\nExecution Time: ");
        if(time_hour > 0)
            System.out.print(time_hour + " Hours, ");
        if(time_min > 0)
            System.out.print(time_min % 60 + " Minutes, ");
        if(time_sec > 0)
            System.out.print(time_sec % 60 + " Seconds, ");
        if(time_ms > 0)
            System.out.print(time_ms % 1E+3 + " MicroSeconds, ");
        if(time_ns > 0)
            System.out.print(time_ns % 1E+6 + " NanoSeconds");
    }
}
4
Pratik Patil

あなたが時計時間が欲しいなら

long start_time = System.currentTimeMillis();
object.method();
long end_time = System.currentTimeMillis();
long execution_time = end_time - start_time;
4
David Nehme

"skaffman"が言ったように、単体テストのメソッドカバレッジツールが呼び出されたメソッドにタイミング情報を透過的に追加するために使用するのと同じように、AOP ORを使用します。

Emma( http://downloads.sourceforge.net/emma/emma-2.0.5312-src.zip?modtime = 1118607545&big_mirror = 0 )のようなオープンソースツールツールによって使用されるコードを見ることができます。他のオープンソースのカバレッジツールは http://prdownloads.sourceforge.net/cobertura/cobertura-1.9-src.zip?download です。

あなたが最終的にあなたが設定したことをうまくやれば、pls。あなたのantタスク/ jarファイルを使ってここでコミュニティと共有しましょう。

4
anjanb

Metrics さまざまな測定器を提供するライブラリを使うことができます。依存関係を追加します。

<dependencies>
    <dependency>
        <groupId>io.dropwizard.metrics</groupId>
        <artifactId>metrics-core</artifactId>
        <version>${metrics.version}</version>
    </dependency>
</dependencies>

環境に合わせて設定してください。

メソッドに @Timed のアノテーションを付けることができます。

@Timed
public void exampleMethod(){
    // some code
}

または で囲まれたコードの一部

final Timer timer = metricsRegistry.timer("some_name");
final Timer.Context context = timer.time();
// timed code
context.stop();

集約されたメトリックは、コンソール、JMX、CSVなどにエクスポートできます。

@Timedメトリックの出力例:

com.example.ExampleService.exampleMethod
             count = 2
         mean rate = 3.11 calls/minute
     1-minute rate = 0.96 calls/minute
     5-minute rate = 0.20 calls/minute
    15-minute rate = 0.07 calls/minute
               min = 17.01 milliseconds
               max = 1006.68 milliseconds
              mean = 511.84 milliseconds
            stddev = 699.80 milliseconds
            median = 511.84 milliseconds
              75% <= 1006.68 milliseconds
              95% <= 1006.68 milliseconds
              98% <= 1006.68 milliseconds
              99% <= 1006.68 milliseconds
            99.9% <= 1006.68 milliseconds
3
Justas

あなたは春のコアプロジェクトからストップウォッチクラスを使用することができます。

コード:

StopWatch stopWatch = new StopWatch()
stopWatch.start();  //start stopwatch
// write your function or line of code.
stopWatch.stop();  //stop stopwatch
stopWatch.getTotalTimeMillis() ; ///get total time

ストップウォッチのためのドキュメンテーション: シンプルなストップウォッチ、いくつかのタスクのタイミングを考慮して、それぞれの指定されたタスクの合計実行時間と実行時間を公開します。 System.currentTimeMillis()の使用を隠し、アプリケーションコードの読みやすさを向上させ、計算エラーの可能性を減らします。このオブジェクトはスレッドセーフになるようには設計されておらず、同期を使用しません。このクラスは通常、本番アプリケーションの一部としてではなく、概念実証中および開発中のパフォーマンスを検証するために使用されます。

3
praveen jain
long startTime = System.currentTimeMillis();
// code goes here
long finishTime = System.currentTimeMillis();
long elapsedTime = finishTime - startTime; // elapsed time in milliseconds
3
Ryan Rodemoyer

数秒で結果が出るようにコードを正解から変更しました。

long startTime = System.nanoTime();

methodCode ...

long endTime = System.nanoTime();
double duration = (double)(endTime - startTime) / (Math.pow(10, 9));
Log.v(TAG, "MethodName time (s) = " + duration);
3
wzbozon

わかりました、これはあなたの関数の単純で単純なタイミングのために使われる単純なクラスです。その下に例があります。

public class Stopwatch {
    static long startTime;
    static long splitTime;
    static long endTime;

    public Stopwatch() {
        start();
    }

    public void start() {
        startTime = System.currentTimeMillis();
        splitTime = System.currentTimeMillis();
        endTime = System.currentTimeMillis();
    }

    public void split() {
        split("");
    }

    public void split(String tag) {
        endTime = System.currentTimeMillis();
        System.out.println("Split time for [" + tag + "]: " + (endTime - splitTime) + " ms");
        splitTime = endTime;
    }

    public void end() {
        end("");
    }
    public void end(String tag) {
        endTime = System.currentTimeMillis();
        System.out.println("Final time for [" + tag + "]: " + (endTime - startTime) + " ms");
    }
}

使用例

public static Schedule getSchedule(Activity activity_context) {
        String scheduleJson = null;
        Schedule schedule = null;
/*->*/  Stopwatch stopwatch = new Stopwatch();

        InputStream scheduleJsonInputStream = activity_context.getResources().openRawResource(R.raw.skating_times);
/*->*/  stopwatch.split("open raw resource");

        scheduleJson = FileToString.convertStreamToString(scheduleJsonInputStream);
/*->*/  stopwatch.split("file to string");

        schedule = new Gson().fromJson(scheduleJson, Schedule.class);
/*->*/  stopwatch.split("parse Json");
/*->*/  stopwatch.end("Method getSchedule"); 
    return schedule;
}

コンソール出力の例:

Split time for [file to string]: 672 ms
Split time for [parse Json]: 893 ms
Final time for [get Schedule]: 1565 ms
2
msysmilu

Java 8では、Instantという名前の新しいクラスが導入されました。ドキュメント通り:

インスタントは、タイムライン上のナノ秒の始まりを表します。このクラスは、マシンの時刻を表すタイムスタンプを生成するのに役立ちます。瞬間の範囲は、長いよりも大きい数の記憶を必要とします。これを実現するために、クラスはlongを表すEpoch-secondsとナノ秒を表すintを格納します。これは常に0から999,999,999の間になります。エポック秒は、1970-01-01T00:00:00Zの標準Javaエポックから測定されます。エポックの後の時点は正の値を持ち、それ以前の時点は負の値を持ちます。エポック秒部分とナノ秒部分の両方について、小さい値よりも大きい値の方が常にタイムライン上で遅くなります。

これは次のように使用できます。

Instant start = Instant.now();
try {
    Thread.sleep(7000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
Instant end = Instant.now();
System.out.println(Duration.between(start, end));

PT7.001Sを印刷します。

2
i_am_zero

時間を知りたいだけならこの方法を試すことができます。

long startTime = System.currentTimeMillis();
//@ Method call
System.out.println("Total time [ms]: " + (System.currentTimeMillis() - startTime));    
2
gifpif

System.nanoTime()は実行時間を測定するための非常に正確なシステムユーティリティです。ただし、プリエンプティブスケジューラモード(デフォルト)で実行している場合、このユーティリティは実際にはCPU時間ではなく実時間を測定します。したがって、システム負荷によっては、実行ごとに実行時間の値が異なることに気付くでしょう。あなたがCPU時間を探すなら、私はあなたのプログラムをリアルタイムモードで走らせることがトリックをすると思う。あなたはRT linuxを使わなければなりません。 link: Linuxによるリアルタイムプログラミング

1
hmitcs

もしJavaがもっと機能的なサポートを持っているなら、それは測定される必要があるアクションがブロックに包まれることができるように、いいだろう:

measure {
   // your operation here
}

Javaではこれは冗長すぎるように見える匿名関数によって行われる可能性があります。

public interface Timer {
    void wrap();
}


public class Logger {

    public static void logTime(Timer timer) {
        long start = System.currentTimeMillis();
        timer.wrap();
        System.out.println("" + (System.currentTimeMillis() - start) + "ms");
    }

    public static void main(String a[]) {
        Logger.logTime(new Timer() {
            public void wrap() {
                // Your method here
                timeConsumingOperation();
            }
        });

    }

    public static void timeConsumingOperation() {
        for (int i = 0; i<=10000; i++) {
           System.out.println("i=" +i);
        }
    }
}
1

これは、グーグルの検索時間が検索に要したのと同じように、きれいに印刷された文字列を整形した秒数の経過です。

        long startTime = System.nanoTime();
        //  ... methodToTime();
        long endTime = System.nanoTime();
        long duration = (endTime - startTime);
        long seconds = (duration / 1000) % 60;
        // formatedSeconds = (0.xy seconds)
        String formatedSeconds = String.format("(0.%d seconds)", seconds);
        System.out.println("formatedSeconds = "+ formatedSeconds);
        // i.e actual formatedSeconds = (0.52 seconds)
1
Timothy Siwula

私のマシンのパフォーマンス測定

  • System.nanoTime():750ns
  • System.currentTimeMillis():18ns

前述のように、System.nanoTime()は経過時間を測定すると考えられています。ループなどに使われている場合は、コストに注意してください。

1
leo

私は簡単なタイマーを実装しました、そしてそれは本当に便利だと思います:

public class Timer{
    private static long start_time;

    public static double tic(){
        return start_time = System.nanoTime();
    }

    public static double toc(){
        return (System.nanoTime()-start_time)/1000000000.0;
    }

}

そうすれば、1つ以上のアクションを計時できます。

Timer.tic();
// Code 1
System.out.println("Code 1 runtime: "+Timer.toc()+" seconds.");
// Code 2
System.out.println("(Code 1 + Code 2) runtime: "+Timer.toc()+"seconds");
Timer.tic();
// Code 3
System.out.println("Code 3 runtime: "+Timer.toc()+" seconds.");
1

javaagent を使用して、Javaクラスのバイト数を変更したり、モニタコードを動的に追加したりできます。githubには、これを実行できるオープンソースのツールがいくつかあります。
自分でやりたいのであれば、 javaagent を実装し、 javassist を使用して監視したいメソッドと、メソッドreturn.itがクリーンになる前の監視コードを変更するだけです。ソースコードがなくてもシステムを監視できます。

1
dingjsh

Java eeで私に役立つ戦略は次のとおりです。

  1. @AroundInvokeでアノテーションが付けられたメソッドでクラスを作成してください。

    @Singleton
    public class TimedInterceptor implements Serializable {
    
        @AroundInvoke
        public Object logMethod(InvocationContext ic) throws Exception {
            Date start = new Date();
            Object result = ic.proceed();
            Date end = new Date();
            System.out.println("time: " + (end.getTime - start.getTime()));
            return result;
        }
    }
    
  2. 監視したいメソッドに注釈を付けます。

    @Interceptors(TimedInterceptor.class)
    public void onMessage(final Message message) { ... 
    

これが役に立つことを願っています。

0