자바에서 두 점 사이의 시간을 재는 방법에는 currentTimeMillis 와 nanoTime가 있다.
이 정적메서드에 대해서는 지난 주에 심층(?) 분석을 해보았다. [JVM] currentTimeMillis vs nanoTime
하지만 직접 날 것(raw)의 메서드로 사용할 대는 응집성이 떨어질 수 있으므로 스톱와치와 같은 실세상과 비슷한 유틸리티 클래스를 이용하면 좋을 것이다.
이 글은 스프링의 StopWatch에 대해 적으려고 하였지만 사실 Apache Commons Lang 유틸리티에도 StopWatch를 가지고 있었다.
스프링의 StopWatch
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/util/StopWatch.html
내부 코드를 살짝 보았는데, 구현은 currentTimeMillis을 통해 하고 있다.
참고로 spring-core에 코드가 있다. 2001년 5월에 추가되었고 스프링의 창시자 로드존슨(Rod Johnson)을 비롯한 Juergen Hoeller, Sam Brannen 가 저자로 적혀있다.
StopWatch 클래스에는 내부 클래스 TaskInfo이 있다.
public static final class TaskInfo {
private final String taskName;
private final long timeMillis;
연결리스트로 관리되고 stop을 할 때마다 추가가 된다. (아래 코드는 가독성을 위해 많은 코드가 지워졌다.)
public class StopWatch {
private final List<TaskInfo> taskList = new LinkedList<>();
public void stop() throws IllegalStateException {
if (this.currentTaskName == null) {
throw new IllegalStateException("Can't stop StopWatch: it's not running");
}
long lastTime = System.currentTimeMillis() - this.startTimeMillis;
this.totalTimeMillis += lastTime;
this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime);
if (this.keepTaskList) {
this.taskList.add(this.lastTaskInfo);
}
++this.taskCount;
this.currentTaskName = null;
}
아파치의 StopWatch
https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/time/StopWatch.html
반면에 Apache Commons Langs의 time 패키지 하위의 StopWatch는 시간 계산을 동시에 두가지 방법을 모두 사용한다.
public class StopWatch {
/**
* The start time.
*/
private long startTime;
/**
* The start time in Millis - nanoTime is only for elapsed time so we
* need to also store the currentTimeMillis to maintain the old
* getStartTime API.
*/
private long startTimeMillis;
public void start() {
if (this.runningState == State.STOPPED) {
throw new IllegalStateException("Stopwatch must be reset before being restarted. ");
}
if (this.runningState != State.UNSTARTED) {
throw new IllegalStateException("Stopwatch already started. ");
}
this.startTime = System.nanoTime();
this.startTimeMillis = System.currentTimeMillis();
this.runningState = State.RUNNING;
}
하지만 stop 메서드를 보면 namoTime()만 스냅샷을 찍는 걸로 보아서 결국 nanoTime()을 시간 계산으로 쓴다는 것을 알 수 있다.
사실은 위에 인스턴스 변수 선언의 주석에도 쓰여있다.
public void stop() {
if (this.runningState != State.RUNNING && this.runningState != State.SUSPENDED) {
throw new IllegalStateException("Stopwatch is not running. ");
}
if (this.runningState == State.RUNNING) {
this.stopTime = System.nanoTime();
}
this.runningState = State.STOPPED;
}
Apache는 nanoTime()을 쓰고 Spring은 currentTimeMillis()을 쓴다.
역시 Ummm님이 스프링의 유틸리티를 싫어하는 데에는 이유가 있었다.
2019년 8월 7일 스프링의 StopWatch 클래스도 단조 증가 시계로 바뀌었다.
https://github.com/spring-projects/spring-framework/issues/23235 참고~
---
2021-09-01 새 에디터에 맞춰 코드 수정 및 업데이트
'Programing > Framework' 카테고리의 다른 글
[Spring] core - Converter 인터페이스 (0) | 2019.03.29 |
---|---|
[SpringBoot] HikariCP의 leakDetectionThreshold 기본값은? (0) | 2019.03.28 |
[Spring Boot] spring-boot-devtools (0) | 2019.03.14 |
[Spring Framework] Java와 Groovy 문법 삽질기 (0) | 2019.03.07 |
[Spock] Internal of spock (Specification) (0) | 2019.02.07 |