2009-08-06 20 views
21

Często koduję zawijam w parze System.nanoTime() w celu ustawienia czasu. Coś takiego jak:Biblioteka wydajności czasu Java

long start = System.nanoTime();  
methodToBeTimed(); 
long elapsedTime = System.nanoTime() - start; 

Czy jest jakaś dobra biblioteka pomiaru czasu, która pomaga w tym problemie? Przyjmowany jest także kod rodzimej społeczności.

NB

profilera nie jest rozwiązaniem tutaj, ponieważ chcę, aby wymusić pewne ograniczenia czasowe w moich testów jednostkowych, więc chcę rozrządu Metody programowo.

+0

Nie rozumiem, czym jest "problem", który próbujesz rozwiązać. Masz jedną linię na górze i jeszcze jedną linię na dole, aby dać ci upływ czasu. I masz jedną zmienną do jej przechowywania. Możesz zawinąć to w klasę lub użyć klasy Stopwatch, ale nie zmniejszysz w żaden sposób złożoności kodu: nadal będziesz potrzebował jednej linii na górze i jednej linii na dole. Czy potrzebujesz pomocy w nagrywaniu i śledzeniu dużej liczby takich czasów? – AgilePro

Odpowiedz

11

Nie użyłem tego, ale ostatnio natknąłem się na perf4j.

+0

@ Mark: nigdy nie słyszałem o tym. Dziękuję bardzo! – dfa

+0

Możesz nawet narysować wykresy za pomocą perf4j ze zintegrowanym serwletem. Jest całkiem niezły. – unludo

+0

perf4j przeniósł się do github https://github.com/perf4j/perf4j – Sebastien

8

Nie bezpośrednią odpowiedź na Twoje pytanie, ale ja też często za pomocą tej końcówki do czasu mojego kodu i po prostu napisał następujący prosty Eclipse -> Surround z szablonu:

long startTime = System.currentTimeMillis(); 
${line_selection}${cursor} 
long totalTime = System.currentTimeMillis() - startTime; 
System.out.println("Total time = " + totalTime); 
System.out.println(); 
+0

Niestety jestem użytkownikiem netbeans - :) – dfa

1

Próbowaliśmy JPerf?

+0

Użyj pamięci podręcznej Google, aby zobaczyć użycie, ewentualnie sprawdź link do xjperf: http://code.google.com/p/xjperf/ – techzen

+0

wydaje się być frontendem dla iperf, czyli "nowoczesna alternatywa dla pomiaru maksymalnej wydajności przepustowości TCP i UDP". To prawda? – dfa

1

Jakiego rodzaju pomocy szukasz w tym problemie? Masz podstawy w miejscu. Masz czas, który upłynął w Nanosekundach, z dokładnością do jakiejkolwiek rozdzielczości, do której jest zdolny podstawowy sprzęt/Sprzęt.

Również ... i wiem, że nie powiedziałeś profilerów ... ale miałem wyjątkowe doświadczenie z YourKit. Udostępnia interfejs API, za pomocą którego można kontrolować profilowanie z zewnątrz. W zależności od tego, jaki jest twój konkretny problem, ten może być wart obejrzenia.

6

jest StopWatch z commons-lang, pozwala także na dzielenie licznika czasu.

+0

miło to zobaczyć, ale tylko hermetyzuje System.nanoTime/System.currentTimeMillis wywołuje – dfa

+0

jest zawsze łatwiejszy w użyciu niż wersja domyślna;) – IAdapter

+0

linkk złamane ... – Pacerier

8

JUnit 4 ma wbudowaną funkcję ograniczenia czasu.

@Test (timeout = X)

powinno załatwić sprawę. X to maksymalna liczba milisekund, jaką metoda może uruchomić.

+0

Brzmi jak zwycięzca dla mnie. –

+0

tak, jest to bardzo podstawowa implementacja, niezbędna jestem dla @Test (timeout = X, repeat = N), a następnie wyświetl średnią – dfa

3

Jeśli używasz Springa, masz już klasę o nazwie StopWatch w swojej ścieżce klas.

1

JETM to dobra biblioteka do robienia tego. Może również dostarczyć min, max i średnie, a także może generować wykresy informacyjne.

0

ręcznie ...

import static java.lang.System.nanoTime; 

/** 
* For testing/debug purposes. 
* 
* <pre> 
* private Stopwatch stopwatch = new Stopwatch(); 
* ... 
* public void method1() { 
*  stopwatch.reset(); 
*  for (...) { 
*   ... 
*   stopwatch.start(); 
*   operation1(); 
*   stopwatch.stop(); 
*   ... 
*  } 
*  System.out.println("operation 1 max timing is " + stopwatch.getMaxLapTime()); 
* } 
* ... 
* public void method2() { 
*  stopwatch.reset(); 
*  for (...) { 
*   ... 
*   stopwatch.start(); 
*   operation2(); 
*   stopwatch.stop(); 
*   ... 
*  } 
*  System.out.println("operation 2 max timing is " + stopwatch.getMaxLapTime()); 
* } 
* </pre> 
* 
* @author Mykhaylo Adamovych 
*/ 
public class Stopwatch { 
    protected long totalTime; 
    protected long maxLapTime; 
    protected long minLapTime = Long.MAX_VALUE; 
    protected long lapsCount; 
    protected long lastThreshold; 

    /** 
    * Human readable time in seconds 
    * 
    * @param nanoTime 
    * @return time in seconds 
    */ 
    public static final String toSeconds(long nanoTime) { 
     return String.format("%.9f", nanoTime/1000000000.0); 
    } 

    public long getAverageLapTime() { 
     if (lapsCount == 0) 
      return 0; 
     return totalTime/lapsCount; 
    } 

    public long getMaxLapTime() { 
     return maxLapTime; 
    } 

    public long getMinLapTime() { 
     return minLapTime; 
    } 

    public long getTotalTime() { 
     return totalTime; 
    } 

    /** 
    * Returns last lap time, process statistic. 
    */ 
    public long lapTime() { 
     return processLapTime(); 
    } 

    private long processLapTime() { 
     if (lastThreshold == 0) 
      throw new IllegalStateException("Stopwatch is stopped."); 
     final long now = nanoTime(); 
     final long lapTime = now - lastThreshold; 
     lapsCount++; 
     totalTime += lapTime; 
     if (lapTime > maxLapTime) 
      maxLapTime = lapTime; 
     if (lapTime < minLapTime) 
      minLapTime = lapTime; 
     lastThreshold = nanoTime(); 
     return lapTime; 
    } 

    /** 
    * Resets statistic and starts. 
    */ 
    public void reset() { 
     totalTime = 0; 
     maxLapTime = 0; 
     minLapTime = Long.MAX_VALUE; 
     lapsCount = 0; 
     start(); 
    } 

    /** 
    * Starts time watching. 
    */ 
    public void start() { 
     lastThreshold = nanoTime(); 
    } 

    /** 
    * Suspends time watching, returns last lap time. 
    */ 
    public long stop() { 
     final long lapTime = processLapTime(); 
     lastThreshold = 0; 
     return lapTime; 
    } 
} 
+1

Nie sądzę, aby Twoja implementacja dla 'minLapTime' zadziałała, ponieważ jest inicjalizowana z najniższą możliwą wartością: 0. Prawdopodobnie powinna być zainicjowana za pomocą (i zresetuj do) 'Long.MAX_VALUE'. – martin

0

Nowością na rynku jest JMH. Jest wykonany pod parasolem projektu openjdk.

0

Właśnie zacząłem używać Java Simon (dawniej on Google Code) i wygląda na to, że jest super! Prosty zestaw stoperów i liczników z kilkoma zależnościami.