[Java] Calendar is too slow

java.util.Calendar 객체를 생성하는 데는 상당한 비용이 소요된다.

즉,

      Calendar.getInstance()


라는 메소드를 호출하여 Calendar 객체를 가져오는 데 걸리는 시간이 상당하다.

     // 현재 시간을 가져오는 보통의 방법
     private static Calendar getCalendar1() {
         return Calendar.getInstance();
     }
 
     // 현재 시간은 아니지만 Calendar 객체를 clone을 통해 가져오는 방법
     private static Calendar getCalendar2() {
         return (Calendar) cal.clone();
     }
 
     // Calendar 객체를 clone을 통해 가져와서 현재 시간으로 만드는 방법
     private static Calendar getCalendar3() {
         Calendar c = (Calendar) cal.clone();
         c.setTimeInMillis(System.currentTimeMillis());
         return c;
     }
 
     // 가장 범용적인 GregorianCalendar 객체를 직접 생성하는 방법
     private static Calendar getCalendar4() {
         Calendar c = new GregorianCalendar();
         return c;
     }


위의 메소드를 약 10만회씩 실행한 결과는 다음과 같다.

 // JDK 1.4
 
 it took 391 (ms)
 it took 187 (ms)
 it took 375 (ms)
 it took 328 (ms)
 
 // JDK 1.5
 
 it took 469 (ms)
 it took 266 (ms)
 it took 421 (ms)
 it took 344 (ms)


JDK 1.4와 1.5 모두 그냥 Calendar 객체를 clone을 통해 만드는 것이 가장 빨랐다. Calendar.getInstance()에 비해 거의 두 배가 빠르다.

따라서 단순히 Calendar 객체가 필요하고 여기에 시간을 다시 지정해야 할 것이라면 clone 방법을 사용하는 것이 가장 좋다.

그럼 만약 현재 시간의 Calendar 객체가 필요하다면?

GregorianCalendar를 사용하지 않는 환경에서는 호환성이 문제가 되겠지만 대부분의 지역에서는 직접 new GregorianCalendar()를 사용하는 것이 가장 효율적이다.

그럼 Calendar 객체간의 시간 비교는 어떨까?

다음 테스트는 Calendar 객체와 현재 시간과의 비교이다. 현재 시간이 아닌 경우에는 결과가 많이 다를 수 있다. 그 이유는 Calendar.getInstance()가 new Date()에 비해 훨씬 비싸기 때문이다. 그리고 new Date() 객체 역시 System.currentTimeMillis()에 비해 매우 비싸다.

     // 현재 시간과 비교할 때 new Date()와 비교
     private static boolean compareCalendar1(Calendar cal) {
         return cal.getTime().after(new Date());
     }
 
     // 현재 시간과 비교할 때 Calendar.getInstance()와 비교
     private static boolean compareCalendar2(Calendar cal) {
         return cal.after(Calendar.getInstance());
     }
 
     // 현재 시간과 비교할 때 System.currentTimeMillis()와 비교
     private static boolean compareCalendar3(Calendar cal) {
         return cal.getTimeInMillis() > System.currentTimeMillis();
     }


역시 10만번 수행 결과는 다음과 같다.


 // JDK 1.4
 
 compare1 took 110 (ms)
 compare2 took 328 (ms)
 compare3 took 15 (ms)
 
 // JDK 1.5
 
 compare1 took 78 (ms)
 compare2 took 360 (ms)
 compare3 took 15 (ms)

댓글

이 블로그의 인기 게시물

[Java] Java G1 GC의 특성에 따른 Full GC 회피 튜닝 방법

엄밀한 사고(Critical Thinking)란 무엇일까

일론 머스크의 First Principle Thinking (제1원리 기반 사고)