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=9460663 및 simongbrown.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.