it-swarm.com.de

Wie kann ich die Ausführung einer Methode in Java zeitlich festlegen?

Wie erhalte ich die Ausführungszeit einer Methode? Gibt es eine Timer-Dienstprogrammklasse für Dinge wie das Timing, wie lange eine Aufgabe usw. dauert?

Die meisten Suchanfragen bei Google geben Ergebnisse für Zeitgeber zurück, die Threads und Aufgaben planen. Dies ist nicht das, was ich möchte.

771
Ogre Psalm33

Es gibt immer den altmodischen Weg:

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

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

Ich gehe mit der einfachen Antwort. Funktioniert bei mir.

long startTime = System.currentTimeMillis();

doReallyLongThing();

long endTime = System.currentTimeMillis();

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

Es funktioniert ganz gut Die Auflösung ist offensichtlich nur auf die Millisekunde genau, was Sie mit System.nanoTime () besser machen können. Es gibt einige Einschränkungen für beide (Zeitplansegmente des Betriebssystems usw.), aber dies funktioniert ziemlich gut.

Durchschnitt über ein paar Läufe (je mehr desto besser) und Sie werden eine anständige Vorstellung bekommen.

177
MBCook

Komm schon Leute! Niemand erwähnte den Guava Weg, das zu tun (was wohl fantastisch ist):

import com.google.common.base.Stopwatch;

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

Das Schöne ist, dass Stopwatch.toString () Zeiteinheiten für die Messung gut auswählt. Das heißt Wenn der Wert klein ist, werden 38 ns ausgegeben, wenn er lang ist, werden 5 m 3s angezeigt

Noch schöner:

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

Hinweis: Für Google Guava ist Java 1.6 + erforderlich.

165

Verwenden von Instant und Duration aus der neuen API von Java 8,

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

ausgänge,

PT5S
127
Sufiyan Ghori

Verwenden Sie einen Profiler (JProfiler, Netbeans Profiler, Visual VM, Eclipse Profiler usw.). Sie erhalten die genauesten Ergebnisse und sind am wenigsten aufdringlich. Sie verwenden den integrierten JVM-Mechanismus für die Profilerstellung, mit dem Sie bei Bedarf auch zusätzliche Informationen wie Stack-Traces, Ausführungspfade und umfassendere Ergebnisse erhalten.

Bei Verwendung eines vollständig integrierten Profilers ist es nicht einfach, eine Methode zu profilieren. Klicken Sie mit der rechten Maustaste auf Profiler -> Zu Stammmethoden hinzufügen. Führen Sie dann den Profiler so aus, als würden Sie einen Testlauf oder Debugger durchführen.

85
James Schek

Sammelte alle möglichen Wege an einem Ort.

Datum

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 ) );

Menschenlesbar Format

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;
}

Guave: Google Stoppuhr JAR "Ein Ziel von Stopwatch ist es, die verstrichene Zeit in Nanosekunden zu messen.

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 LangJAR " Stoppuhr bietet eine komfortable API für Timings.

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 Date Time API von Java 8 "Ein Duration Objekt repräsentiert einen Zeitraum zwischen zwei - Instant Objekte.

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 bietet StopWatch eine Utility-Klasse zum Messen der verstrichenen Zeit in Java.

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());
}

Ausgabe:

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]
77
Yash

Dies ist wahrscheinlich nicht das, was Sie von mir wollten, aber dies ist eine gute Verwendung von AOP. Peitschen Sie einen Proxy-Interceptor um Ihre Methode und nehmen Sie dort das Timing vor.

Das Was, Warum und Wie von AOP würde den Rahmen dieser Antwort leider sprengen, aber so würde ich es wahrscheinlich tun.

Edit: Hier ist ein Link zu Spring AOP, um Ihnen den Einstieg zu erleichtern, wenn Sie daran interessiert sind. Dies ist die für Java am leichtesten zugängliche Implementierung von AOP.

Angesichts der sehr einfachen Vorschläge aller anderen sollte ich auch hinzufügen, dass AOP für den Fall gedacht ist, dass Sie nicht möchten, dass Dinge wie Timing in Ihren Code eindringen. In vielen Fällen ist diese einfache und unkomplizierte Herangehensweise jedoch in Ordnung.

37
skaffman

System.currentTimeMillis(); IS KEIN guter Ansatz zur Messung der Leistung Ihrer Algorithmen. Es misst die Gesamtzeit, die Sie als Benutzer auf dem Computerbildschirm verbringen. Es enthält auch die Zeit, die für alles auf Ihrem Computer im Hintergrund ausgeführte verbraucht wird. Dies kann einen großen Unterschied machen, wenn auf Ihrer Workstation viele Programme ausgeführt werden.

Bei der richtigen Vorgehensweise wird das Paket Java.lang.management verwendet.

Von http://nadeausoftware.com/articles/2008/03/Java_tip_how_get_cpu_and_user_time_benchmarking Website:

  • "Benutzerzeit" ist die Zeit, die zum Ausführen des eigenen Codes Ihrer Anwendung benötigt wird.
  • "Systemzeit" ist die Zeit, die für die Ausführung des Betriebssystemcodes für Ihre Anwendung aufgewendet wurde (z. B. für E/A).

getCpuTime() Methode gibt Ihnen die Summe dieser:

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;
    }

}
35
TondaCZE

Mit Java 8 können Sie mit jedem normalen Methoden auch so etwas machen:

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

mit TimeIt wie:

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;
}
}

Mit dieser Methode können Sie überall in Ihrem Code eine einfache Zeitmessung durchführen, ohne ihn zu beschädigen. In diesem einfachen Beispiel drucke ich nur die Zeit. Können Sie einen Schalter für TimeIt hinzufügen, z. um nur die Zeit in DebugMode oder so zu drucken.

Wenn Sie mit Funktion arbeiten, können Sie Folgendes tun:

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;
    };
}
25
Stefan

Wir können auch die StopWatch-Klasse von Apache-Commons zum Messen der Zeit verwenden.

Beispielcode

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());
17
Narayan

Nur eine kleine Wendung, wenn Sie keine Werkzeuge verwenden und Methoden mit geringer Ausführungszeit zeitlich festlegen möchten: Führen Sie sie mehrmals aus und verdoppeln Sie dabei jedes Mal die Anzahl der Ausführungen, bis Sie eine Sekunde erreichen, oder so. Daher hat der Zeitpunkt des Aufrufs von System.nanoTime usw. und die Genauigkeit von System.nanoTime keinen großen Einfluss auf das Ergebnis.

    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");

Natürlich gelten die Einschränkungen bezüglich der Verwendung der Wanduhr: Einflüsse der JIT-Kompilierung, mehrere Threads/Prozesse usw. Daher müssen Sie die Methode viel zuerst ausführen, so dass die JIT Der Compiler erledigt seine Arbeit, wiederholt diesen Test mehrmals und benötigt die niedrigste Ausführungszeit.

15

Zu diesem Zweck verwenden wir die Anmerkungen AspectJ und Java. Wenn wir die Ausführungszeit für eine Methode kennen müssen, können wir sie einfach mit Anmerkungen versehen. Eine weiter fortgeschrittene Version könnte eine eigene Protokollebene verwenden, die zur Laufzeit aktiviert und deaktiviert werden kann.

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;
  }
  [...]
}
13
murdochjohn

Wirklich guter Code.

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;
  }
11
iceberg

JEP 230: Microbenchmark Suite

FYI, JEP 230: Microbenchmark Suite ist ein OpenJDK Projekt an:

Fügen Sie dem JDK-Quellcode eine grundlegende Reihe von Mikrobenchmarks hinzu, und erleichtern Sie Entwicklern das Ausführen vorhandener Mikrobenchmarks und das Erstellen neuer.

Diese Funktion ist in Java 12 eingetroffen.

Java Microbenchmark Harness (JMH)

Schauen Sie sich für frühere Versionen von Java das Projekt Java Microbenchmark Harness (JMH) an, auf dem JEP 230 basiert.

11
Basil Bourque

Sie können Perf4j verwenden. Sehr cooles Dienstprogramm. Die Bedienung ist einfach

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; 
}

Weitere Informationen finden Sie in Entwicklerhandbuch

Edit: Projekt scheint tot

9
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()));
    }

}
8
Maciek Kreft

Mit AOP/AspectJ und @Loggable Annotation von jcabi-aspekte können Sie es einfach und kompakt machen:

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

Jeder Aufruf dieser Methode wird an die SLF4J-Protokollierungsfunktion mit der Protokollierungsstufe DEBUG gesendet. Und jede Protokollmeldung enthält die Ausführungszeit.

7
yegor256

Grundsätzlich mache ich Variationen davon, aber wenn man bedenkt, wie die Hotspot-Kompilierung funktioniert, muss man die ersten Messungen ausschließen und sicherstellen, dass die Methode in einer realen Anwendung (anwendungsspezifisch lesen) verwendet wird, um genaue Ergebnisse zu erzielen.

Wenn die JIT beschließt, diese zu kompilieren, variieren Ihre Zahlen stark. Also sei dir einfach bewusst

7
luke

Spring bietet eine Utility-Klasse org.springframework.util.StopWatch gemäß JavaDoc:

Einfache Stoppuhr, die das Timing einer Reihe von Aufgaben ermöglicht und die Gesamtlaufzeit und die Laufzeit für jede benannte Aufgabe anzeigt.

Verwendungszweck:

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());

Ausgabe:

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

Mit Aspekten:

@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;
}
6
Sunil Manheri

Ich habe eine Methode geschrieben, um die Ausführungszeit der Methode in einer gut lesbaren Form auszudrucken. Um beispielsweise die Fakultät von 1 Million zu berechnen, sind ungefähr 9 Minuten erforderlich. Die Ausführungszeit wird also gedruckt als:

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

Der Code ist hier:

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");
    }
}
6
Pratik Patil

Dafür gibt es verschiedene Möglichkeiten. Normalerweise greife ich nur auf Folgendes zurück:

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

oder dasselbe mit System.nanoTime ();

Für etwas mehr auf der Benchmark-Seite der Dinge scheint es auch dieses zu geben: http://jetm.void.fm/ Habe es aber nie versucht.

6
Horst Gutmann

Wenn Sie Wanduhrzeit wollen

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

Wie "skaffman" sagte, können Sie mit AOP OR das Laufzeit-Bytecode-Weben verwenden, genau wie Unit-Test-Methoden-Coverage-Tools, um aufgerufene Methoden transparent mit Timing-Informationen zu versehen.

Sie können sich den Code ansehen, der von Open-Source-Tools wie Emma ( http://downloads.sourceforge.net/emma/emma-2.0.5312-src.zip?modtime=1118607545&big_mirror= ) verwendet wird. Das andere OpenSource-Berichterstattungstool ist http://prdownloads.sourceforge.net/cobertura/cobertura-1.9-src.zip?download .

Wenn es Ihnen irgendwann gelingt, das zu tun, wofür Sie sich entschlossen haben, wenden Sie sich an pls. Teile es der Community hier mit deinen Ameisenaufgaben/Gläsern.

5
anjanb

Sie können die Bibliothek Metrics verwenden, die verschiedene Messinstrumente bereitstellt. Abhängigkeit hinzufügen:

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

Und konfigurieren Sie es für Ihre Umgebung.

Methoden können mit @ Timed kommentiert werden:

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

oder Stück Code umhüllt mit Timer :

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

Aggregierte Metriken können in Konsole, JMX, CSV oder andere exportiert werden.

Beispiel für die Ausgabe von @Timed Metriken:

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
4
Justas

Sie können die Stoppuhrklasse aus dem Federkernprojekt verwenden:

Code:

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

Dokumentation für die Stoppuhr: Einfache Stoppuhr, die das Timing einer Reihe von Aufgaben ermöglicht, die Gesamtlaufzeit und die Laufzeit für jede benannte Aufgabe anzeigt. Verbirgt die Verwendung von System.currentTimeMillis (), verbessert die Lesbarkeit des Anwendungscodes und reduziert Wahrscheinlichkeit von Berechnungsfehlern Beachten Sie, dass dieses Objekt nicht threadsicher ist und keine Synchronisierung verwendet Diese Klasse wird normalerweise verwendet, um die Leistung während der Konzeptprüfung und in der Entwicklung zu überprüfen, und nicht als Teil von Produktionsanwendungen.

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

Ich habe den Code von der richtigen Antwort geändert, um das Ergebnis in Sekunden zu erhalten:

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);
4
wzbozon

Ok, dies ist eine einfache Klasse, die zum einfachen Timing Ihrer Funktionen verwendet wird. Es gibt ein Beispiel darunter.

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");
    }
}

Anwendungsbeispiel:

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;
}

Beispiel für die Konsolenausgabe:

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

In Java 8 wird eine neue Klasse namens Instant eingeführt. Laut doc:

Instant repräsentiert den Beginn einer Nanosekunde auf der Zeitachse. Diese Klasse ist nützlich, um einen Zeitstempel für die Maschinenzeit zu generieren. Die Reichweite eines Augenblicks erfordert die Speicherung einer Zahl, die größer als eine lange ist. Um dies zu erreichen, speichert die Klasse eine lange darstellende Epoche und eine ganze Nanosekunde, die immer zwischen 0 und 999.999.999 liegen. Die Epochen-Sekunden werden aus der Standard-Java -Epoche von 1970-01-01T00: 00: 00Z gemessen, wobei Zeitpunkte nach der Epoche positive Werte haben und frühere Zeitpunkte negative Werte haben. Sowohl für den Epochensekunden- als auch für den Nanosekunden-Teil ist ein größerer Wert immer später als ein kleinerer Wert auf der Zeitlinie.

Dies kann verwendet werden als:

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

Es wird PT7.001S gedruckt.

3
i_am_zero

Sie können diesen Weg versuchen, wenn Sie nur die Zeit wissen wollen.

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

System.nanoTime() ist ein ziemlich genaues Systemdienstprogramm zum Messen der Ausführungszeit. Aber seien Sie vorsichtig, wenn Sie im präventiven Scheduler-Modus (Standardeinstellung) arbeiten, misst dieses Dienstprogramm tatsächlich die Wanduhrzeit und nicht die CPU-Zeit. Aus diesem Grund stellen Sie möglicherweise fest, dass je nach Systembelastung von Ausführung zu Ausführung unterschiedliche Werte für die Ausführungszeit verwendet werden. Wenn Sie nach CPU-Zeit Ausschau halten, reicht es aus, wenn Sie Ihr Programm im Echtzeitmodus ausführen. Sie müssen RT Linux verwenden. Link: Echtzeitprogrammierung unter Linux

1
hmitcs

Es wäre schön, wenn Java eine bessere funktionale Unterstützung hätte, so dass die Aktion, die gemessen werden muss, in einen Block eingeschlossen werden könnte:

measure {
   // your operation here
}

In Java könnte dies durch anonyme Funktionen geschehen, die zu ausführlich aussehen

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

Hier ist eine hübsche gedruckte Zeichenfolge, die für formatierte Sekunden bereit ist, ähnlich der Zeit, die die Google-Suche für die Suche benötigt hat:

        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

Leistungsmessungen auf meinem Computer

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

Wie bereits erwähnt, misst System.nanoTime () die verstrichene Zeit. Seien Sie sich nur der Kosten bewusst, wenn Sie eine Schlaufe oder ähnliches verwenden.

1
leo

Ich habe einen einfachen Timer implementiert, und ich denke, dass er wirklich nützlich ist:

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;
    }

}

Auf diese Weise können Sie eine oder mehrere Aktionen zeitlich festlegen:

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

Sie können javaagent verwenden, um die Klassenbytes Java zu ändern. Fügen Sie die Monitorcodes dynamisch hinzu. Es gibt einige Open-Source-Tools auf dem Github, die dies für Sie tun können.
Wenn Sie es selbst tun möchten, implementieren Sie einfach javaagent, verwenden Sie javassist, um die Methoden zu ändern, die Sie überwachen möchten, und den Monitorcode vor Ihrem method return.it ist sauber und Sie können Systeme überwachen, die Sie nicht einmal über Quellcode verfügen.

1
dingjsh

Eine Strategie, die für mich in Java ee funktioniert, war:

  1. Erstellen Sie eine Klasse mit einer Methode, die mit @AroundInvoke kommentiert ist.

    @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. Kommentieren Sie die Methode, die Sie überwachen möchten:

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

Ich hoffe das kann helfen.

0