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


85

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

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

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

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

답변:


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

2
정말 실제로 nanoTime을해야한다
유진

6
nanoTime이 아니어야합니다. rhu의 대답을 참조하십시오.
fabspro 2013

4
여기서 "파이널"을 사용한 특별한 이유가 있습니까? 해당 키워드를 삭제하면 어떻게됩니까?
dijxtra

9
@dijxtra using final은 실수로 할당 할 수 없다는 장점이 있습니다 (익명 클래스 액세스 등의 다른 장점도 있음). 이 코드에서는 차이가 없습니다. 모든 것을 만들고 필요한 경우 final에만 final단일화하는 것은 매우 일반적인 관행 입니다.
wchargin 2013-08-28

1
테스트 할 코드는 시간 측정과 함께 여러 번 실행되어야하며 첫 번째 결과는 삭제되어야합니다. 첫 번째는 클래스 로딩 시간 등을 포함 할 것입니다. 여러 번 실행하면 더 유용하고 신뢰할 수있는 평균을 얻을 수 있습니다.
Arun Ramakrishnan

34

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


9

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

final long startTime = System.currentTimeMillis();

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

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

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

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

BalusC의 대답도 정확합니다. 필요한 타이머 해상도와 타이밍이 필요한 이유에 따라 다릅니다.
Jonathan Feinberg

9

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

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


Windows의 타이머는 기본적으로 특별히 좋은 해상도를 가지고 있지 않습니다. 이 고성능 타이머도하지만 훨씬 더 어렵다 C에서도 사용하고 자바 (AFAIK)는 JNI없이 해커의 수준이 썽크이 저에 대한 액세스를 제공하지 않습니다.
Donal Fellows

1
nanoTime()하나의 문제가 있습니다 (적어도 Windows에서는). 타임 스탬프는 프로세서 코어에 따라 다릅니다. 한 코어에는 "시작"타임 스탬프가 있고 다른 코어에는 "중지"타임 스탬프가 있기 때문에 실행 시간이 음수 인 프로그램이 있습니다.
gustafc 2010

3

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

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

final long t0 = System.currentTimeMillis()

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

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


자동 생성기 코드를 가리키는 +1. 나는 항상 비슷한 문장을 사용하며 코드 템플릿 삽입에 대해 몰랐다. 이클립스로 그것을하는 방법을 알아 냈고 확실히 도움이 될 것입니다!
Jason

모든 Codehaus 서비스가 종료되었습니다. 이제 링크가 끊어졌습니다.
naXa

2

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

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

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


2

다음은 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);

1

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

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

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


1

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

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 에게 특별히 감사드립니다 . 를 참조하십시오 여기 .



0

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]

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

0

System.currentTimeMillis ()를 사용하는 것이 적절한 방법입니다. 그러나 명령 줄을 사용하고 전체 프로그램의 시간을 대략적으로 빠르게 측정하려면 다음을 고려하십시오.

time java App

코드와 앱 시간을 수정할 수 없습니다.


이것은 코드를 실행하는 방법에 따라 다릅니다. 서버를 실행하는 코드라면 잘못된 시작 시간을 포함하게됩니다.
Arun Ramakrishnan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.