programing tip

Java 프로그램 실행 속도를 측정하는 방법

itbloger 2020. 10. 7. 07:25
반응형

Java 프로그램 실행 속도를 측정하는 방법


Java 프로그램 실행 시간은 어떻게됩니까? 이 작업을 수행하기 위해 어떤 클래스를 사용해야하는지 잘 모르겠습니다.

다음과 같은 것을 찾고 있습니다.

// Some timer starts here
for (int i = 0; i < length; i++) {
  // Do something
}
// End timer here

System.out.println("Total execution time: " + totalExecutionTime);

final long startTime = System.currentTimeMillis();
for (int i = 0; i < length; i++) {
  // Do something
}
final long endTime = System.currentTimeMillis();

System.out.println("Total execution time: " + (endTime - startTime));

System#nanoTime()멀티 코어 CPU에서 경과 시간을 기록하기 위해 안정적으로 사용할 수없는 몇 가지 문제가 있습니다. 각 코어는 자체 TSC ( Time Stamp Counter )를 유지합니다 .이 카운터는 나노 시간을 얻는 데 사용됩니다 (실제로는 CPU 부팅 이후의 틱 수).

따라서 OS가 코어를 동기화 상태로 유지하기 위해 TSC 시간 왜곡을 수행하지 않는 한, 스레드가 초기 시간 판독 값을 취할 때 하나의 코어에서 예약 된 다음 다른 코어로 전환되면 상대적 시간이 산발적으로 뒤로 점프하는 것처럼 보일 수 있습니다. 그리고 앞으로.

나는 얼마 전에 AMD / Solaris에서 두 타이밍 포인트 사이의 경과 시간이 때때로 음수 값이나 예기치 않게 큰 양수로 되돌아 오는 것을 관찰했습니다. AMD PowerNow!를 강제하는 데 필요한 Solaris 커널 패치와 BIOS 설정이있었습니다. 그것을 해결하는 것처럼 보였다.

또한 System#nanoTime()VirtualBox 환경에서 Java 사용할 때 지금까지 수정되지 않은 버그 (AFAIK)가 있습니다. java.util.concurrency패키지의 대부분이 나노 시간에 의존 하기 때문에 모든 종류의 기괴한 간헐적 스레딩 문제를 야기합니다 .

또한보십시오:

System.nanoTime ()은 완전히 쓸모가 없습니까? http://vbox.innotek.de/pipermail/vbox-trac/2010-January/135631.html


사용할 수 있습니다 System#nanoTime(). 실행 전후에 그것을 얻고 수학을하십시오. System#currentTimeMillis()정밀도가 더 높기 때문에 위에서 선호 됩니다. 사용 된 하드웨어 및 플랫폼에 따라 경과 시간에 잘못된 간격이 발생할 수 있습니다. Windows에서 Core2Duo를 사용하면 약 0 ~ 15ms 사이에는 실제로 아무것도 계산할 수 없습니다.

고급 도구는 프로파일 러 입니다.


현재 시스템 시간 (밀리 초)을 얻습니다.

final long startTime = System.currentTimeMillis();

그런 다음 수행 할 작업을 수행합니다.

for (int i = 0; i < length; i++) {
  // Do something
}

그런 다음 소요 된 시간을 확인합니다.

final long elapsedTimeMillis = System.currentTimeMillis() - startTime;

간단한 작업의 경우 System.currentTimeMillis () 가 작동 할 수 있습니다.

실제로 내 IDE가 설정되어 "t0"을 입력하면 다음 줄이 생성됩니다.

final long t0 = System.currentTimeMillis()

그러나 좀 더 복잡한 경우에는 다음과 같이 통계적 시간 측정을 사용하고 싶을 것입니다 (조금 아래로 스크롤하여 표준 편차 등을 포함하여 표현 된 시간 측정을보십시오).

http://perf4j.codehaus.org/devguide.html


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

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

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


startTime=System.currentTimeMillis()루프 상단에서 시작 시간을 길게 사용

long endTime= System.currentTimeMillis();루프의 끝 외부에 두십시오 . 밀리 초 단위의 런타임을 얻으려면 값을 빼야합니다.

나노초 단위의 시간을 원한다면 System.nanoTime()


다음은 Java에서 실행 시간을 찾는 몇 가지 방법입니다.

1) System.nanoTime ()

long startTime = System.nanoTime();
.....your code....
long endTime   = System.nanoTime();
long totalTime = endTime - startTime;
System.out.println("Execution time in nanoseconds  : " + totalTime);
System.out.println("Execution time in milliseconds : " + totalTime / 1000000);

2) System.currentTimeMillis ()

long startTime = System.currentTimeMillis();
.....your code....
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
System.out.println("Execution time in milliseconds  : " + totalTime);

3) Instant.now ()

long startTime = Instant.now().toEpochMilli();
.....your code....
long endTime = Instant.now().toEpochMilli();
long totalTime = endTime - startTime;
System.out.println("Execution time in milliseconds: " + totalTime);

또는

Instant start = Instant.now();
.....your code....
Instant end = Instant.now();
Duration interval = Duration.between(start, end);
System.out.println("Execution time in seconds: " +interval.getSeconds());

4) Date.getTime ()

long startTime = new Date().getTime();
.....your code....
long endTime = new Date().getTime();
long totalTime = endTime - startTime;
System.out.println("Execution time in milliseconds: " + totalTime);

측정하려는 코드를 람다로 사용하는 고차 함수를 만들었습니다.

class Utils {

    public static <T> T timeIt(String msg, Supplier<T> s) {
        long startTime = System.nanoTime();
        T t = s.get();
        long endTime = System.nanoTime();
        System.out.println(msg + ": " + (endTime - startTime) + " ns");
        return t;
    }

    public static void timeIt(String msg, Runnable r) {
       timeIt(msg, () -> {r.run(); return null; });
    }
}

다음과 같이 부르십시오.

Utils.timeIt("code 0", () ->
        System.out.println("Hallo")
);

// in case you need the result of the lambda
int i = Utils.timeIt("code 1", () ->
        5 * 5
);

산출:

코드 0 : 180528 ns
코드 1 : 12003 ns

중복을 줄이는 데 도움을 준 Andy Turner 에게 특별히 감사드립니다 . 를 참조하십시오 여기 .


를보세요 System.currentTimeMillis().


Perf4J를 사용해 볼 수도 있습니다. 원하는 것을 수행하는 깔끔한 방법이며 설정된 시간 범위 동안 평균, 최소, 최대, 표준 편차 및 초당 트랜잭션과 같은 집계 된 성능 통계에 도움이됩니다. http://perf4j.codehaus.org/devguide.html 에서 발췌 :

StopWatch stopWatch = new LoggingStopWatch();

try {
    // the code block being timed - this is just a dummy example
    long sleepTime = (long)(Math.random() * 1000L);
    Thread.sleep(sleepTime);
    if (sleepTime > 500L) {
        throw new Exception("Throwing exception");
    }

    stopWatch.stop("codeBlock2.success", "Sleep time was < 500 ms");
} catch (Exception e) {
    stopWatch.stop("codeBlock2.failure", "Exception was: " + e);
}

산출:

INFO: start[1230493236109] time[447] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493236719] time[567] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493237286] time[986] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493238273] time[194] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493238467] time[463] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493238930] time[310] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239241] time[610] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493239852] time[84] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239937] time[30] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239968] time[852] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]

public class someClass
{
   public static void main(String[] args) // your app start point
   {
       long start = java.util.Calendar.getInstance().getTimeInMillis();

       ... your stuff ...

       long end = java.util.Calendar.getInstance().getTimeInMillis();
       System.out.println("it took this long to complete this stuff: " + (end - start) + "ms");
   }
}

Using System.currentTimeMillis() is the proper way of doing this. But, if you use command line, and you want to time the whole program approximately and quickly, think about:

time java App

which allows you not to modify the code and time your App.

참고URL : https://stackoverflow.com/questions/2572868/how-to-time-java-program-execution-speed

반응형