Java'da bir yöntemin yürütülmesini nasıl zamanlayabilirim?


834
  1. Bir yöntemin yürütme süresini nasıl alabilirim?
  2. TimerBir görevin ne kadar sürdüğü vb. Zamanlama gibi şeyler için bir yardımcı sınıf var mı ?

Google'da yapılan aramaların çoğu, iş parçacıkları ve görevleri zamanlayan zamanlayıcılar için sonuç döndürüyor; bu benim istediğim şey değil.


JAMon API, geliştiricilerin üretim uygulamalarının performansını ve ölçeklenebilirliğini kolayca izlemelerine olanak tanıyan ücretsiz, basit, yüksek performanslı, iş parçacığı güvenli bir Java API'dir. JAMon isabetleri, yürütme sürelerini (toplam, ort, min, maks, std dev) ve daha fazlasını izler. http://jamonapi.sourceforge.net/ indir: http://sourceforge.net/project/showfiles.php?group_id=96550
Mike Pone

1
Ayrıca Apache Commons Lang StopWatch sınıfına da bakmak isteyebilirsiniz . Basit ama kullanışlı bir yardımcı sınıf.


Evet, StopWatch bunun için harika.
Shubham Pandey

InstantSınıfı kullanan Java 8 : stackoverflow.com/a/30975902/1216775
akhil_mittal

Yanıtlar:


1207

Her zaman eski moda bir yol vardır:

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

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

233
aslında, onun "yeni moda" çünkü java5 kadar eklenmedi nanoTime kullandım
John Gardner

11
Bu (ya da System.currentTimeMillis () kullanarak) genellikle Java'da yaptığı gibi görünüyor ... zaten gördüğüm. Hala Timer t = new Timer () gibi gösterişli yerleşik bir sınıfın olmaması beni şaşırtıyor. Dize s = t.getElapsed (biçim); vb ...
Ogre Psalm33

18
nanoTime, doğruluğu currentTimeMillis () 'den daha iyi garanti etmez, ancak genellikle yapar. forums.sun.com/thread.jspa?messageID=9460663 ve simongbrown.com/blog/2007/08/20/…
James Schek

10
Tabii ki, sonucu bozabilecek derleyici / JVM optimizasyonları gibi mikro-kıyaslamanın tuzaklarını hatırlamak her zaman önemlidir = 8-)
Yuval

18
Bir istisna atılırsa endTime kullanılmayacağından son olarak bir bloğa gerek yoktur.
Peter Lawrey

197

Basit bir cevapla gidiyorum. Benim için çalışıyor.

long startTime = System.currentTimeMillis();

doReallyLongThing();

long endTime = System.currentTimeMillis();

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

Oldukça iyi çalışıyor. Çözünürlük sadece milisaniyedir, System.nanoTime () ile daha iyisini yapabilirsiniz. Her ikisinde de bazı sınırlamalar vardır (işletim sistemi zamanlama dilimleri vb.), Ancak bu oldukça iyi çalışır.

Ortalama birkaç (daha iyi) çalışır ve iyi bir fikir alırsınız.


51
Aslında, System.currentTimeMillis () yalnızca 15 ms'nin üzerinde doğrudur. Gerçekten düşük değerler için güvenilir olamaz. Bunun çözümü (belirtildiği gibi) System.nanoTime ();
Steve g

Tamam, Steve g'nin yorumunu okuyana kadar bunu resmi cevap olarak kabul etmek üzereydim. Harika bir haber, Steve!
Ogre Psalm33

4
nanoTime (), currentTimeMillis'ten daha iyi doğruluğu garanti etmez, ancak birçok JVM uygulamasının nanoTime ile daha iyi doğruluğu vardır.
James Schek

5
@JamesSchek Başka bir yerde bu özdeş yorumdan daha önce bahsettiğim gibi, ifadelerinizi gerçekten izlemeniz gerekiyor; en az olduğu kadar kararlınanoTime olduğu garanti edilmektedir . docs.oracle.com/javase/7/docs/api/java/lang/…currentTimeMillis
b1nary.atr0phy

Bunun küçük bir avantajı, currentTimeMillisbunun gerçek bir zaman damgası olması ve başlangıç ​​/ bitiş zamanlarını da günlüğe kaydetmek nanoTimeiçin kullanılabilmesidir. ."
Brad Parks

177

Hadi beyler! Kimse bunu yapmanın Guava yolundan bahsetmedi (tartışmasız harika):

import com.google.common.base.Stopwatch;

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

Güzel olan şey, Stopwatch.toString () öğesinin ölçüm için zaman birimleri seçmede iyi bir iş çıkarmasıdır. Yani değer küçükse, 38 ns çıktı verir, uzunsa 5m 3s gösterir

Daha da güzel:

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

Not: Google Guava, Java 1.6+ sürümünü gerektirir


21
Ne yazık ki, Guava'nın Kronometresi güvenli değildir. Bunu zor yoldan öğrendim.
Dexter Legaspi

6
@DexterLegaspi Deneyiminizle çok ilgilenirsiniz! Paylaşmak ister misiniz?
Siddhartha

1
Kronometreyi paralel olarak kullanmak start(), arka arkaya birden çok kez arama yapmanızı sağlar stop().
Mingwei Samuel

141

Java 8'in yeni API'sındaki Anında Arama ve Süre özelliğini kullanarak ,

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

çıktılar,

PT5S

2
Teşekkürler, PT önde olmadan sonuç çıktısını nasıl alabilirim?
java123999

1
Yöntemle ilgili sorun, Instant uygulamasının milli ve nano saniye hassasiyetini problem etmemesi. Ref: stackoverflow.com/questions/20689055/…
prashantsunkari

8
@ java123999: Arayabilirsiniz Duration.between(start, end).getSeconds(). Durationayrıca, örneğin toMillis()milisaniyeye dönüştüren diğer zaman birimlerine dönüştürme yöntemlerine de sahiptir .
Emil Lunde

100

Tüm olası yolları bir araya topladık.

tarih

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

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

Okunabilir Biçim

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

Guava: Google Kronometre JAR « Kronometrenin amacı, geçen süreyi nanosaniye olarak ölçmektir.

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 , zamanlamalar için uygun bir API sağlar.

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 -Saat

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'den Java tarih saati API'si «Bir Duration nesnesi, iki Instant nesnesi arasındaki süreyi temsil eder .

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'da geçen süreyi ölçmek için StopWatch yardımcı programı sınıfısağlar.

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

Çıktı:

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]

Guava, Apache Commons ve Spring Framework'ün kronometresi güvenli değildir. Üretim kullanımı için güvenli değildir.
Deepak Puthraya

@DeepakPuthraya hangi kütüphane kullanılacak, hangisi üretim kullanımı için güvenli?
gaurav

1
@DeepakPuthraya Java tarih saati API sağlanan java 8 kullanabilirsiniz. Hangisi basit.
Yash

IMO bu yazı, her çözümün sistem çıkışlarını da göstermesi durumunda fayda sağlayacaktır.
BAERUS

87

Bir profiler kullanın (JProfiler, Netbeans Profiler, Visual VM, Eclipse Profiler, vb.). En doğru sonuçları alırsınız ve en az müdahaleci olur. Profil oluşturma için yerleşik JVM mekanizmasını kullanırlar; bu da size yığın izleri, yürütme yolları ve gerekirse daha kapsamlı sonuçlar gibi ek bilgiler verebilir.

Tam entegre bir profil oluşturucuyu kullanırken, bir yöntemi profillemek kesinlikle önemsizdir. Sağ tıklayın, Profiler -> Kök Yöntemlerine Ekle. Ardından profil oluşturucuyu tıpkı bir test çalıştırması veya hata ayıklayıcı yapıyormuş gibi çalıştırın.


Bu da harika bir öneriydi ve bu cevabı okuduğumda benim için "duh" ampul anlarından biri. Projemiz JDeveloper kullanıyor, ama kontrol ettim ve eminim, yerleşik bir profil var!
Ogre Psalm33

2
Java 7 build 40'tan (sanırım) eski JRockits Uçuş Kaydedicisini java'ya dahil ettiler (Java Görev Kontrolü için arama)
Niels Bech Nielsen


Örneğin, Visual VM ile Java'da yöntemin nasıl çalıştırılacağı?
okwap

41

Muhtemelen söylememi istediğin şey bu değildi, ama bu AOP'nin iyi bir kullanımı. Bir proxy önleme yöntemini çırpın ve orada zamanlama yapın.

Ne yazık ki, neden ve nasıl AOP bu cevabın kapsamı dışında, ama ne yazık ki ben böyle yapardım.

Düzenleme: Eğer istekli iseniz, başlamak için Bahar AOP bir bağlantı . Bu, Java için karşılaştığınız en erişilebilir AOP uygulamasıdır.

Ayrıca, herkesin çok basit önerileri göz önüne alındığında, kodunuzu istila etmek için zamanlama gibi şeyler istemediğinizde AOP için olduğunu eklemeliyim. Ancak birçok durumda, bu tür basit ve kolay bir yaklaşım iyidir.


3
İşte Spring ile bunu nasıl yapacağınıza dair bir eğitici: veerasundar.com/blog/2010/01/…
David Tinker

39

System.currentTimeMillis();Algoritmalarınızın performansını ölçmek için iyi bir yaklaşım DEĞİLDİR. Bilgisayar ekranını izleyen bir kullanıcı olarak yaşadığınız toplam süreyi ölçer. Ayrıca, arka planda bilgisayarınızda çalışan her şey tarafından harcanan zamanı da içerir. İş istasyonunuzda çalışan birçok program olması durumunda bu çok büyük bir fark yaratabilir.

Doğru yaklaşım java.lang.managementpaketi kullanmaktır .

Gönderen http://nadeausoftware.com/articles/2008/03/java_tip_how_get_cpu_and_user_time_benchmarking web:

  • "Kullanıcı saati", uygulamanızın kendi kodunu çalıştırmak için harcanan zamandır.
  • "Sistem saati", uygulamanız adına işletim sistemi kodunu çalıştırmak için harcanan süredir (G / Ç gibi).

getCpuTime() yöntemi size bunların toplamını verir:

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

}

4
Bu kesinlikle iyi bir nokta, "kullanıcı zamanı" (duvar saati zamanı), özellikle çok iş parçacıklı bir programda her zaman büyük bir performans ölçüsü değildir.
Ogre Psalm33

Aradığım cevap bu.
ZhaoGang

30

Java 8 ile her normal yöntemle böyle bir şey yapabilirsiniz :

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

TimeIt ile:

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

Bu yöntemle kodunuzda herhangi bir yeri bozmadan kolay ölçüm yapabilirsiniz. Bu basit örnekte sadece zamanı yazdırıyorum. TimeIt için bir Anahtar ekleyebilir misiniz, örneğin yalnızca DebugMode'da zamanı yazdırmak için.

İşlev ile çalışıyorsanız böyle bir şey yapabilirsiniz:

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

Bu, diğer çözümlerden çok daha iyi görünüyor. Bahar AOP'ye daha yakın, ancak bundan daha hafif. Gerçek Java 8 yolu! +1 Teşekkürler!
Amit Kumar

Belki bu sana iyi geliyor çünkü Stefan yeni java fonksiyonları kullanıyor. Ama bunun okunması ve anlaşılması çok zor olduğunu düşünüyorum.
Stimpson Cat

18

Ayrıca zamanı ölçmek için Apache ortaklarının StopWatch sınıfını kullanabiliriz.

Basit kod

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

15

Sadece küçük bir bükülme, takım kullanmıyorsanız ve düşük yürütme süresi olan zaman yöntemleri istiyorsanız: birçok kez çalıştırın, her seferinde bir saniyeye ulaşana kadar kaç kez yürütüldüğünü iki katına çıkarın. Böylece, System.nanoTime çağrısının zamanı ve benzeri, ne de System.nanoTime'ın doğruluğu sonucu çok fazla etkilemez.

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

Tabii ki, duvar saatini kullanma hakkındaki uyarılar geçerlidir: JIT-derlemesinin etkileri, çoklu iş parçacıkları / süreçler vb. Bu nedenle, önce JIT derleyicisinin işini yapması için önce yöntemi çok kez yürütmeniz gerekir , sonra bu testi birkaç kez tekrarlayın ve en düşük yürütme süresini alın.


13

Bu amaçla AspectJ ve Java ek açıklamalarını kullanıyoruz. Bir yöntem için yürütme süresini bilmemiz gerekiyorsa, basit bir açıklama ekleyebiliriz. Daha gelişmiş bir sürüm, çalışma zamanında etkinleştirilebilen ve devre dışı bırakılabilen kendi günlük düzeyini kullanabilir.

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


11

Gerçekten iyi bir kod.

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

3
Aslında soru, bir yöntemin nasıl biçimlendirileceği değil, süresinin nasıl hesaplanacağıydı. Ancak bu soru oldukça eskidir (neredeyse dört yıl!). Yanıt mevcut yanıtlara yeni ve önemli bir şey katmayacaksa, eski ileti dizilerini yeniden canlandırmaktan kaçının.
Leigh

1
Ve sonuna kalan milisleri eklemek için aşağıdaki değişiklikleri yapın: long millis = TimeUnit.MILLISECONDS.toMillis(duration) - TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(duration)); if (days == 0) { res = String.format("%02d:%02d:%02d.%02d", hours, minutes, seconds, millis); } else { res = String.format("%dd%02d:%02d:%02d.%02d", days, hours, minutes, seconds, millis); }
Rick Barkhouse

10

Perf4j kullanabilirsiniz . Çok güzel bir yardımcı program. Kullanımı basit

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

Daha fazla bilgi Geliştirici Kılavuzu'nda bulunabilir

Edit: Proje ölü gibi görünüyor


1
Perf4j de güzel istatistikler üretebilir .
Paaske

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

}

1
Oluşturma sistemi ve bağımlı OTS'yi kurduğunuzda ve basit bir zamanlayıcı sınıfı içeren başka bir OTS paketinde çekmeyi istemiyorsanız, kendi basit sınıfınızı yuvarlayın.
Ogre Psalm33

7

Temelde bunun varyasyonlarını yapıyorum, ancak hotspot derlemesinin nasıl çalıştığını göz önünde bulundurarak, doğru sonuçlar elde etmek istiyorsanız, ilk birkaç ölçümü atmanız ve yöntemi gerçek bir dünya (uygulamaya özgü) uygulamasında kullandığınızdan emin olmanız gerekir.

JIT derlemeye karar verirse, sayılarınız büyük ölçüde değişecektir. bu yüzden sadece farkında ol


7

AOP / AspectJ ve jcabi özelliklerinden@Loggable ek açıklama kullanarak bunu kolay ve kompakt yapabilirsiniz:

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

Bu yönteme yapılan her çağrı, DEBUGkayıt seviyeli SLF4J kayıt tesisine gönderilecektir . Ve her günlük mesajı yürütme süresini içerecektir.


7

Spring, JavaDoc'a göre org.springframework.util.StopWatch yardımcı programı sınıfı sağlar :

Adlandırılmış her görev için toplam çalışma süresini ve çalışma süresini gösteren, çeşitli görevlerin zamanlamasına izin veren basit kronometre.

Kullanımı:

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

Çıktı:

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

Unsurları ile:

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

AspectJ ile kullanmak mümkün mü?
zygimantus

7

Yöntem yürütme süresini çok okunabilir bir biçimde yazdırmak için bir yöntem yazdım. Örneğin, 1 Milyon faktöriyeli hesaplamak yaklaşık 9 dakika sürer. Böylece yürütme süresi şu şekilde yazdırılır:

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

Kod burada:

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

Bunu yapmanın birkaç yolu var. Ben normalde sadece böyle bir şey kullanarak geri düşer:

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

veya System.nanoTime () ile aynı şey;

Kıyaslama tarafında daha fazla bir şey için bu da var gibi görünüyor: http://jetm.void.fm/ Yine de denemedim.


6

Çeşitli ölçüm cihazları sağlayan Metrik kütüphanesini kullanabilirsiniz . Bağımlılık ekle:

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

Ve ortamınız için yapılandırın.

Yöntemler @Timed ile açıklanabilir :

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

veya Zamanlayıcı ile sarılmış kod parçası :

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

Birleştirilmiş metrikler konsol, JMX, CSV veya diğerlerine aktarılabilir.

@Timed metrik çıktı örneği:

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

5

Duvar saati zamanı istiyorsanız

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


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

4

Saniyeler içinde sonuç almak için kodu doğru cevaptan değiştirdim:

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

Yaylı çekirdek projesinden kronometre sınıfını kullanabilirsiniz:

Kod:

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

Kronometre Dokümantasyonu: Bir dizi görevin zamanlamasına izin veren, her bir görev için toplam çalışma süresini ve çalışma süresini gösteren basit kronometre . System.currentTimeMillis () kullanımını gizler, uygulama kodunun okunabilirliğini artırır ve hesaplama hataları olasılığını azaltır. Bu nesnenin iş parçacığı için güvenli olarak tasarlanmadığını ve eşitleme kullanmadığını unutmayın. Bu sınıf normalde üretim uygulamalarının bir parçası olarak değil, kavramların kanıtı sırasında ve geliştirme sırasında performansı doğrulamak için kullanılır.


3

Sadece zamanı bilmek istiyorsanız bu şekilde deneyebilirsiniz.

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

3

Tamam, bu fonksiyonlarınızın basit zamanlaması için kullanılacak basit bir sınıftır. Bunun altında bir örnek var.

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

Kullanım örneği:

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

Konsol çıkışı örneği:

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

3

Java 8'de yeni bir sınıf Instanttanıtıldı. Doc başına:

Anlık, zaman çizgisindeki nanosaniyenin başlangıcını temsil eder. Bu sınıf, makine zamanını temsil etmek için bir zaman damgası oluşturmak için kullanışlıdır. Bir anın aralığı, uzuntan daha büyük bir sayının depolanmasını gerektirir. Bunu başarmak için sınıf, her zaman 0 ile 999,999,999 arasında olacak uzun bir temsil saniyesini ve saniyenin nanosaniyesini temsil eden bir int depolar. Dönem-saniye 1970-01-01T00: 00: 00Z standart Java döneminden ölçülür, burada dönemden sonraki anlar pozitif değerlere sahiptir ve önceki anlar negatif değerlere sahiptir. Hem dönem hem de nanosaniye parçalar için, zaman çizgisinde her zaman daha küçük bir değerden daha büyük bir değer olur.

Bu şu şekilde kullanılabilir:

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

Yazdırır PT7.001S.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.