2008-12-15 4 views
199

В Java, каковы последствия производительности и ресурса использованияSystem.currentTimeMillis() по сравнению с новой датой() против Calendar.getInstance(). GetTime()

System.currentTimeMillis() 

против

new Date() 

против

Calendar.getInstance().getTime() 

Как я понимаю, System.currentTimeMillis() является наиболее эффективным. Однако в большинстве приложений эта длинная ценность должна быть преобразована в Дату или какой-либо подобный объект, чтобы сделать что-либо значимое для людей.

ответ

197

System.currentTimeMillis(), очевидно, наиболее эффективным , так как он даже не создает объект, но new Date() действительно только тонкая обертка о длинной, так что это не далеко позади. Calendar, с другой стороны, относительно медленный и очень сложный, поскольку он имеет дело со значительной сложностью и всеми странностями, присущими датам и временам (високосные годы, летнее сбережение, временные интервалы и т. Д.).

Это вообще хорошая идея, чтобы иметь дело только с длинными временными метками или Date объектов в пределах вашего приложения, и использовать только Calendar, когда вы на самом деле нужно выполнять вычисления даты/времени, или формат даты для отображения их пользователю. Если вам нужно много чего сделать, использование Joda Time, вероятно, хорошая идея для более чистого интерфейса и лучшей производительности.

+1

В чем разница между меткой времени и currentMillis? – pinkpanther 2015-07-10 10:43:24

12

Я предпочитаю использовать значение, возвращаемое System.currentTimeMillis() для всех видов расчетов и только использовать Calendar или Date, если мне нужно, чтобы действительно отобразить значение, которое читается людьми. Это также предотвратит 99% ваших ошибок на летнее время. :)

22

Если вы используете дату, я настоятельно рекомендую вам использовать jodatime, http://joda-time.sourceforge.net/. Используя System.currentTimeMillis() для полей, которые являются, даты звучат как очень плохая идея, потому что у вас будет много бесполезного кода.

Как дата, так и календарь серьезно увязаны, и Календарь определенно является худшим исполнителем их всех.

Я бы посоветовал вам использовать System.currentTimeMillis(), когда вы на самом деле работает с миллисекундах, например, как этот

long start = System.currentTimeMillis(); 
    .... do something ... 
long elapsed = System.currentTimeMillis() -start; 
+25

Я хотел бы прокомментировать это, потому что ваш пример - это одна из вещей, которые вы должны * НЕ использовать System.currentTimeMillis(); он не является монотонным источником синхронизации, поэтому вы не можете надежно вычислить прошедшее с ним время. Если системные часы изменяются во время выполнения кода, который вы выполняете, вы получите странные (например, отрицательные) результаты. Вместо использования System.nanoTime(), который * является * монотонным *, если * базовая система поддерживает такой источник синхронизации (см. Http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6458294) – rem 2014-04-09 14:53:40

+0

Система .currentTimeMillis сам по себе не зависит от часового пояса. Изменение системного времени повлияет на System.nanotime так же, как System.currentTimeMillis – Viktor 2017-06-27 16:00:41

33

Глядя на JDK, внутренний конструктор Calendar.getInstance() имеет следующее:

public GregorianCalendar(TimeZone zone, Locale aLocale) { 
    super(zone, aLocale); 
    gdate = (BaseCalendar.Date) gcal.newCalendarDate(zone); 
    setTimeInMillis(System.currentTimeMillis()); 
} 

поэтому он автоматически делает то, что вы предлагаете. Конструктор Дейта по умолчанию выполняется следующим образом:

public Date() { 
    this(System.currentTimeMillis()); 
} 

Так что на самом деле не нужно, чтобы получить системное время специально, если вы хотите сделать некоторые математику с ней, прежде чем создавать свой календарь/Date объект с ним. Также мне нужно порекомендовать joda-time для использования в качестве замены для собственных классов календаря/даты Java, если ваша цель - много работать с расчетами даты.

+1

, что указатель на конструктор Date прибил его! Благодаря! – 2016-03-04 10:11:16

7

В зависимости от вашего приложения, вы можете рассмотреть возможность использования System.nanoTime().

+0

Почему его вопрос касался ресурсов и производительности, nanoTime() использует больше ресурсов – WolfmanDragon 2008-12-15 22:17:23

+0

Я упомянул об этом, потому что это вариант, который никто не предлагал. Плакат не указал платформу. Ошибка SDN 6876279 показывает, что currentTimeMillis() и nanoTime() принимают примерно одинаковые версии некоторых версий JDK. Плакат также не уточнил их потребности в точности, для которых исходный список может быть неадекватным. – MykennaC 2010-05-28 18:14:50

+4

Позднее, как это может быть, все примеры в вопросе имеют абсолютное представление о том, какое время это, например. 1,348,770,313,071 млн. С начала эпохи Unix. Время, в течение которого `nanoTime` возвращается, относительное (обычно к началу программы) и было бы бессмысленным, если бы вы попытались превратить его в дату. – Dunes 2012-09-27 18:28:33

11

На моей машине я попытался проверить его. Мой результат:

 
Calendar.getInstance().getTime() (*1000000 times) = 402ms 
new Date().getTime(); (*1000000 times) = 18ms 
System.currentTimeMillis() (*1000000 times) = 16ms 

Не забывайте о GC (если вы используете Calendar.getInstance() или new Date())

3

Я попытался это:

 long now = System.currentTimeMillis(); 
     for (int i = 0; i < 10000000; i++) { 
      new Date().getTime(); 
     } 
     long result = System.currentTimeMillis() - now; 

     System.out.println("Date(): " + result); 

     now = System.currentTimeMillis(); 
     for (int i = 0; i < 10000000; i++) { 
      System.currentTimeMillis(); 
     } 
     result = System.currentTimeMillis() - now; 

     System.out.println("currentTimeMillis(): " + result); 

И результат был:

Дата() : 199

currentTimeMillis(): 3

0

System.currentTimeMillis(), очевидно, самый быстрый, потому что это только один вызов метода, и сборщик мусора не требуется.

Смежные вопросы