Java에서 메소드 실행 시간을 어떻게 설정합니까?


834
  1. 메소드의 실행 시간은 어떻게 얻습니까?
  2. Timer작업 소요 시간 등 의 유틸리티 클래스가 있습니까?

Google 검색의 대부분은 스레드와 작업을 예약하는 타이머에 대한 결과를 반환하지만 이는 내가 원하는 것이 아닙니다.


JAMon API는 개발자가 프로덕션 애플리케이션의 성능 및 확장 성을 쉽게 모니터링 할 수있는 무료의 단순하고 안전한 스레드 안전 Java API입니다. JAMon은 적중, 실행 시간 (총, 평균, 최소, 최대, 표준 개발) 등을 추적합니다. http://jamonapi.sourceforge.net/ 다운로드 : http://sourceforge.net/project/showfiles.php?group_id=96550
Mike Pone

1
Apache Commons Lang StopWatch 클래스 를 살펴볼 수도 있습니다 . 간단하지만 유용한 유틸리티 클래스.


예, 스톱워치가 좋습니다.
Shubham Pandey

자바 8 사용하여 Instant클래스 : stackoverflow.com/a/30975902/1216775
akhil_mittal

답변:


1207

항상 구식 방법이 있습니다.

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

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

233
실제로, "새로운 방식"은 javaTime까지 추가되지 않은 nanoTime을 사용했기 때문입니다.
John Gardner

11
이 (또는 System.currentTimeMillis () 사용)는 Java에서 일반적으로 수행되는 방식 인 것 같습니다 ... 어쨌든 본 것입니다. Timer t = new Timer ()와 같이, 내장 된 내장 클래스가 없다는 것이 여전히 약간의 기대입니다. 문자열 s = t.getElapsed (형식); 기타 ...
오우거 시편

18
nanoTime은 currentTimeMillis ()보다 정확도를 보장하지는 않지만 일반적으로 그렇지 않습니다. forums.sun.com/thread.jspa?messageID=9460663simongbrown.com/blog/2007/08/20/…
James Schek

10
물론, 결과를 왜곡 할 수있는 컴파일러 / JVM 최적화와 같은 마이크로 벤치마킹의 함정을 항상 기억하는 것이 중요합니다 = 8-)
Yuval

18
예외가 발생하면 endTime이 사용되지 않으므로 finally 블록이 필요하지 않습니다.
Peter Lawrey

197

나는 간단한 대답으로 간다. 나를 위해 작동합니다.

long startTime = System.currentTimeMillis();

doReallyLongThing();

long endTime = System.currentTimeMillis();

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

꽤 잘 작동합니다. 해결 방법은 밀리 초에 불과하며 System.nanoTime ()으로 더 잘 수행 할 수 있습니다. 운영 체제 일정 조각 등에는 두 가지 제한 사항이 있지만 이것은 잘 작동합니다.

두 번의 런을 평균하면 (더 좋을수록) 괜찮은 아이디어를 얻게됩니다.


51
실제로 System.currentTimeMillis ()는 15ms 이상 정확합니다. 정말 낮은 값의 경우 신뢰할 수 없습니다. 이에 대한 해결책은 언급 한 바와 같이 System.nanoTime ()입니다.
Steve g

좋아, 나는 Steve g의 의견을 읽을 때까지 이것을 공식 답변으로 받아들이려고했다. 대단하다, 스티브!
Ogre Psalm33

4
nanoTime ()은 currentTimeMillis보다 정확도를 보장하지 않지만 많은 JVM 구현은 nanoTime에 대해 더 나은 정확도를 갖습니다.
James Schek

5
@JamesSchek 이미 다른 곳에서 동일한 주석에 대해 언급했듯이, 당신은 당신의 말을 조심해야합니다. 최소한만큼nanoTime 확실한 것이 보장 됩니다 . docs.oracle.com/javase/7/docs/api/java/lang/…currentTimeMillis
b1nary.atr0phy

한 가지 작은 장점은 currentTimeMillis실제 타임 스탬프이며 시작 / 종료 시간을 기록하는 데 사용될 nanoTime수 있지만 "경과 시간을 측정하는 데만 사용할 수 있으며 시스템 또는 벽시계 시간의 다른 개념과는 관련이 없습니다. "
Brad Parks

177

얘들 아! 아무도 구아바의 방법을 언급 하지 않았습니다 (아마도 굉장합니다) :

import com.google.common.base.Stopwatch;

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

좋은 점은 Stopwatch.toString ()이 측정 할 시간 단위를 선택하는 것입니다. 즉, 값이 작 으면 38ns를 출력하고, 길면 5m 3을 표시합니다

더 좋은 :

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

참고 : Google Guava에는 Java 1.6 이상이 필요합니다


21
불행히도 구아바의 스톱워치는 스레드 안전하지 않습니다. 나는 이것을 어려운 방법으로 배웠다.
Dexter Legaspi 2014

6
@DexterLegaspi 귀하의 경험에 매우 관심이 있으십니까! 공유 할까?
Siddhartha

1
스톱워치를 병렬로 사용하면 한 start()번에 여러 번 전화를 걸 수 있습니다 (와 동일 stop()).
Mingwei Samuel 17 년

141

Java 8의 새로운 API에서 Instant and Duration 을 사용하여

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

출력,

PT5S

2
감사합니다 .PT를 앞에 두지 않고 어떻게 결과를 출력 할 수 있습니까?
java123999

1
방법의 문제점은 Instant가 milli 및 nano second precision에 문제를 일으키지 않는다는 것입니다. 참조 : stackoverflow.com/questions/20689055/…
prashantsunkari

8
@ java123999 : 호출 할 수 있습니다 Duration.between(start, end).getSeconds(). Duration또한 다른 시간 단위로 변환하는 방법 (예 : toMillis()밀리 초로 변환)이 있습니다.
Emil Lunde

100

가능한 모든 방법을 한 곳에 모았습니다.

데이트

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

체계. 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;
}

구아바 : 구글 스톱워치 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()) );

요다 시간

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 « Duration 객체는 두 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]

Guava, Apache Commons 및 Spring Framework의 스톱워치는 스레드로부터 안전하지 않습니다. 프로덕션 용도로는 안전하지 않습니다.
Deepak Puthraya 2016 년

@DeepakPuthraya 그렇다면 어떤 라이브러리를 사용해야합니까? 프로덕션 사용에 안전한가요?
gaurav

1
@DeepakPuthraya는 Java 8 제공 Java 날짜 시간 API를 사용할 수 있습니다. 어느 것이 간단합니다.
Yash

IMO이 게시물은 모든 솔루션에 시스템 출력 결과가 표시되는 경우 도움이됩니다.
BAERUS

87

프로파일 러 (JProfiler, Netbeans Profiler, Visual VM, Eclipse Profiler 등)를 사용하십시오. 가장 정확한 결과를 얻을 수 있으며 가장 방해가되지 않습니다. 프로파일 링에 내장 된 JVM 메커니즘을 사용하여 스택 추적, 실행 경로 및 필요한 경우보다 포괄적 인 결과와 같은 추가 정보를 제공 할 수 있습니다.

완전히 통합 된 프로파일 러를 사용하는 경우 분석법 프로파일 링이 쉽지 않습니다. 프로파일 러-> 루트 메소드에 추가를 마우스 오른쪽 단추로 클릭하십시오. 그런 다음 테스트 실행 또는 디버거를 수행하는 것처럼 프로파일 러를 실행하십시오.


이것은 또한 큰 제안이었고,이 답변을 읽을 때 저에게 "duh"전구 순간 중 하나입니다. 우리 프로젝트는 JDeveloper를 사용하지만 필자가 확인하고 충분히 내장되어 있습니다.
오우거 시편

2
Java 7 빌드 40 (제 생각에)에는 이전 JRockits Flight Recorder가 Java (Java Mission Control 검색)로 포함되었습니다.
Niels Bech Nielsen


예를 들어 Visual VM으로 Java에서 메소드 실행을 얻는 방법은 무엇입니까?
okwap

41

이것은 아마 당신이 말하고 싶지 않은 것이지만 이것은 AOP를 잘 사용하는 것입니다. 메소드 주변에 프록시 인터셉터를 채운 후 타이밍을 수행하십시오.

AOP의 대상, 이유 및 방법은 슬프게도이 답변의 범위를 벗어나지 만, 그렇게 할 가능성이 있습니다.

편집 : 여기에 관심이 있다면 Spring AOP에 대한 링크 가 있습니다. 이것은 Iive가 java를 위해 제공하는 가장 액세스 가능한 AOP 구현입니다.

또한 다른 모든 사람들의 매우 간단한 제안을 고려할 때 AOP는 코드에 침입하는 타이밍과 같은 것을 원하지 않을 때를 위해 추가해야합니다. 그러나 많은 경우에 이러한 종류의 간단하고 쉬운 접근 방식이 좋습니다.


3
다음은 Spring에서이를 수행하는 방법에 대한 튜토리얼입니다. veerasundar.com/blog/2010/01/…
David Tinker

39

System.currentTimeMillis();알고리즘의 성능을 측정하는 좋은 방법은 아닙니다. 사용자가 컴퓨터 화면을 보면서 경험 한 총 시간을 측정합니다. 또한 백그라운드에서 컴퓨터에서 실행되는 다른 모든 데 소비되는 시간도 포함됩니다. 워크 스테이션에서 많은 프로그램을 실행하는 경우 큰 차이를 만들 수 있습니다.

올바른 접근 방식은 java.lang.management패키지를 사용하고 있습니다.

에서 http://nadeausoftware.com/articles/2008/03/java_tip_how_get_cpu_and_user_time_benchmarking의 웹 사이트 :

  • "사용자 시간"은 응용 프로그램 자체 코드를 실행하는 데 소요 된 시간입니다.
  • "시스템 시간"은 애플리케이션 대신 (예 : I / O) OS 코드를 실행하는 데 소요 된 시간입니다.

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

}

4
이것은 특히 멀티 스레드 프로그램에서 "사용자 시간"(벽시계 시간)이 항상 성능을 측정하는 것은 아니라는 점입니다.
오우거 시편 33

이것이 내가 찾고있는 대답입니다.
ZhaoGang

30

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

이 방법을 사용하면 코드의 어느 곳에서나 중단없이 쉽게 시간을 측정 할 수 있습니다. 이 간단한 예에서 나는 단지 시간을 인쇄합니다. 예를 들어 DebugMode 등에서 시간 만 인쇄하기 위해 TimeIt 용 스위치를 추가 할 수 있습니다.

Function 으로 작업하는 경우 다음과 같은 작업을 수행 할 수 있습니다.

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

이것은 다른 솔루션보다 훨씬 나아 보입니다. Spring AOP에 더 가깝지만 그보다 가볍습니다. 진정한 자바 8 방법! +1 감사합니다!
Amit Kumar

Stefan이 멋진 새로운 Java 함수를 사용하고 있기 때문에 아마도 이것이 당신에게 좋을 것입니다. 그러나 나는 이것이 읽고 이해하기가 어렵다고 생각합니다.
Stimpson Cat

18

또한 시간 측정을 위해 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());

15

툴링을 사용하지 않고 실행 시간이 짧은 메소드의 시간을 측정하려면 약간의 트위스트를하십시오. 매번 실행하십시오. 매번 1 초에 도달 할 때까지 실행되는 횟수를 두 배로 늘리십시오. 따라서 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 컴파일의 영향, 다중 스레드 / 프로세스 등의 영향을 미칩니다. 따라서 JIT 컴파일러가 작동하도록 먼저 메소드 여러 번 먼저 실행해야합니다. 이 테스트를 여러 번 반복하고 가장 낮은 실행 시간을 갖습니다.


13

이를 위해 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;
  }
  [...]
}

13

JEP 230 : 마이크로 벤치 마크 스위트

참고로, JEP 230 : Microbenchmark Suite 는 다음을 수행하는 OpenJDK 프로젝트입니다.

JDK 소스 코드에 기본 마이크로 벤치 마크 제품군을 추가하고 개발자가 기존 마이크로 벤치 마크를 쉽게 실행하고 새로운 마이크로 벤치 마크를 작성할 수 있습니다.

이 기능은 Java 12에 도착했습니다 .

자바 마이크로 벤치 마크 하니스 (JMH)

이전 버전의 Java의 경우 JEP 230이 기반으로하는 JMH (Java Microbenchmark Harness) 프로젝트를 살펴보십시오 .


11

정말 좋은 코드입니다.

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
실제로 질문은 형식화 방법이 아니라 메서드에 걸리는 시간을 계산하는 방법이었습니다. 그러나이 질문은 꽤 오래되었습니다 (거의 4 년입니다!). 응답이 기존 응답보다 새롭고 중요한 것을 추가하지 않는 한 오래된 스레드를 부활시키지 마십시오.
Leigh

1
나머지 밀리를 끝에 추가하려면 다음과 같이 변경하십시오. 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 를 사용할 수 있습니다 . 매우 멋진 유틸리티. 사용법은 간단하다

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

자세한 내용은 개발자 안내서를 참조하십시오

편집 : 프로젝트가 죽은 것 같습니다


1
Perf4j는 또한 좋은 통계를 생성 할 수 있습니다 .
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
빌드 시스템과 종속 OTS가 이미 설정되어 있고 유틸리티 타이머 클래스가 포함 된 다른 OTS 패키지를 가져 오는 것을 원하지 않으면 간단한 클래스를 롤링하는 것이 좋습니다.
오우거 시편 33

7

나는 기본적으로 이것의 변형을 수행하지만, 핫스팟 컴파일의 작동 방식을 고려할 때 정확한 결과를 얻으려면 처음 몇 가지 측정을 버리고 실제 (응용 프로그램 특정 읽기) 응용 프로그램에서 방법을 사용해야합니다.

JIT가 컴파일하기로 결정하면 숫자가 크게 달라질 수 있습니다. 그러니 그냥 알아


7

jcabi-aspects의 AOP / AspectJ 및 @Loggable주석을 사용 하면 쉽고 컴팩트하게 할 수 있습니다.

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

이 메소드에 대한 모든 호출은 DEBUG로깅 레벨의 SLF4J 로깅 기능으로 전송됩니다 . 그리고 모든 로그 메시지에는 실행 시간이 포함됩니다.


7

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

AspectJ와 함께 사용할 수 있습니까?
zygimantus

7

메소드 실행 시간을 훨씬 읽기 쉬운 형식으로 인쇄하는 메소드를 작성했습니다. 예를 들어, 1 백만의 계승을 계산하려면 약 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");
    }
}

6

몇 가지 방법이 있습니다. 나는 보통 다음과 같은 것을 사용하는 것으로 돌아갑니다.

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

또는 System.nanoTime ()과 동일합니다.

벤치마킹 측면에서 더 많은 것을 위해 이것도 있습니다 : http://jetm.void.fm/ 결코 시도하지 마십시오.


6

다양한 측정 도구를 제공 하는 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
}

또는 Timer로 싸인 코드 :

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

5

벽시계 시간을 원한다면

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

5

"skaffman"이 말했듯이 AOP를 사용하거나 단위 테스트 메소드 적용 툴이 호출 된 메소드에 타이밍 정보를 투명하게 추가하는 데 사용하는 것과 같이 런타임 바이트 코드 직조를 사용할 수 있습니다.

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. 개미 작업 / 항아리와 함께 여기 커뮤니티와 다시 공유하십시오.


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

4

몇 초 안에 결과를 얻기 위해 정답에서 코드를 수정했습니다.

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

스프링 코어 프로젝트에서 스톱워치 클래스를 사용할 수 있습니다.

암호:

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

시간을 알고 싶다면이 방법을 시도해보십시오.

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

3

자, 이것은 간단한 간단한 함수 타이밍에 사용되는 간단한 클래스입니다. 아래에 예가 있습니다.

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

3

Java 8에는 새로운 클래스 Instant가 도입되었습니다. 의사에 따라 :

순간은 타임 라인에서 나노초의 시작을 나타냅니다. 이 클래스는 머신 타임을 나타내는 타임 스탬프를 생성하는 데 유용합니다. 인스턴트의 범위에는 긴 것보다 큰 수의 저장이 필요합니다. 이를 달성하기 위해 클래스는 long을 나타내는 초 (epoch-seconds)와 int (초)를 나타내며, 항상 0에서 999,999,999 사이입니다. 에포크 초는 표준 Java 에포크 1970-01-01T00 : 00 : 00Z에서 측정되며 에포크 이후의 순간은 양수 값을 가지며 이전 순간은 음수 값을 갖습니다. 에포크 초 및 나노초 부분 모두에 대해, 더 큰 값은 항상 더 작은 값보다 타임 라인에서 늦습니다.

이것은 다음과 같이 사용될 수 있습니다 :

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.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.