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
'programing tip' 카테고리의 다른 글
Capybara에서 부모 노드를 얻는 방법은 무엇입니까? (0) | 2020.10.07 |
---|---|
jQuery로 기본 링크 클릭 동작을 중지하는 방법 (0) | 2020.10.07 |
숨겨진 및 내부 API를 사용할 수있는 Android SDK를 어떻게 빌드합니까? (0) | 2020.10.07 |
magit와 덩어리를 나누기 (0) | 2020.10.07 |
R에서 루프가 느린 이유는 무엇입니까? (0) | 2020.10.07 |