System.currentTimeMillis () проти нової дати () проти календаря.getInstance (). GetTime ()


239

У Java, які наслідки використання та ефективність використання ресурсів у Java

System.currentTimeMillis() 

vs.

new Date() 

vs.

Calendar.getInstance().getTime()

Як я розумію, System.currentTimeMillis()це найефективніше. Однак у більшості застосувань це довге значення потрібно було б перетворити на дату чи якийсь подібний об'єкт, щоб зробити щось важливе для людини.

Відповіді:


242

System.currentTimeMillis()очевидно, є найбільш ефективною, оскільки вона навіть не створює об'єкт, але new Date()насправді є лише тонкою обгорткою довгою, тому вона не відстає. Calendarз іншого боку, є відносно повільним і дуже складним, оскільки має справу зі значно складністю та всіма дивацтвами, притаманними датам та часам (високосні роки, економія денного світла, часові пояси тощо).

Як правило, це гарна ідея мати справу лише з довгими часовими позначками або Dateоб'єктами у вашій програмі та використовувати їх лише Calendarтоді, коли вам потрібно виконати обчислення дати / часу або відформатувати дати їх відображення користувачеві. Якщо вам доведеться зробити багато цього, використання Joda Time - це, мабуть, хороша ідея, для більш чистого інтерфейсу та підвищення продуктивності.


2
Яка різниця між часовою міткою та поточноюМіллі?
pinkpanther

1
@pinkpanther: "часова мітка" зазвичай використовується для опису цілого чи довгого, який описує момент часу, коли його інтерпретують як секунди або мілісекунди з моменту "початку епохи". Іншими словами, currentTimeMillis () повертає часову позначку.
Майкл Боргвардт

43

Дивлячись на 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());
}

Тож дійсно не потрібно конкретно отримувати системний час, якщо ви не хочете займатися цим математикою перед створенням об’єкта Календар / Дата. Крім того, я мушу рекомендувати joda-time використовувати в якості заміни власних класів календарів / дат Java, якщо ваша мета багато працювати з обчисленнями дат.


22

Якщо ви використовуєте побачення, я настійно раджу використовувати jodatime, http://joda-time.sourceforge.net/ . Використання System.currentTimeMillis()для полів, які є датами, звучить як дуже погана ідея, оскільки ви отримаєте безліч непотрібного коду.

І дата, і календар серйозно зайняті, і Календар, безумовно, найгірший з них.

Я б радив вам використовувати, System.currentTimeMillis()коли ви фактично працюєте з мілісекундами, наприклад, як це

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

28
Я хотів прокоментувати це, оскільки ваш приклад - це саме одна з речей, для яких НЕ слід використовувати систему System.currentTimeMillis (); це не монотонне джерело годинника, тому ви не можете достовірно обчислити минулий час з ним. Якщо системний годинник буде змінено під час виконання коду, який ви призначаєте, ви отримаєте дивні (наприклад, негативні) результати. Замість цього використовуйте System.nanoTime (), який є монотонним, якщо базальна система підтримує таке джерело годинника (див. Bugs.java.com/bugdatabase/view_bug.do?bug_id=6458294 )
рем

Сам System.currentTimeMillis не впливає на часовий пояс. Зміна системного часу вплине на System.nanotime так само, як System.currentTimeMillis
Віктор

12

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


12

На своїй машині я спробував це перевірити. Мій результат:

Calendar.getInstance (). GetTime () (* 1000000 разів) = 402ms
нова дата (). getTime (); (* 1000000 разів) = 18 мс
System.currentTimeMillis () (* 1000000 разів) = 16 мс

Не забувайте про GC (якщо ви використовуєте Calendar.getInstance()або new Date())


1
цікаво, чи буде різниця, якщо багато потоків називатимуть однаковим між іншими
обробками

7

Залежно від вашої програми, ви можете розглянути можливість використання System.nanoTime()замість цього.


Чому, його питання стосувалося ресурсів та продуктивності, nanoTime () використовує більше ресурсів
WolfmanDragon

Я згадував це, тому що це варіант, який ніхто інший не запропонував. Плакат не вказав платформу. Помилка SDN 6876279 передбачає, що currentTimeMillis () та nanoTime () приймають приблизно те саме в деяких версіях JDK. Плакат також не вказав їх потреби в точності, для яких оригінальний список може бути недостатнім.
MykennaC

4
Як пізніше це може бути, усі приклади у питанні мають абсолютне поняття, який саме час є. 1,348,770,313,071 млн. З моменту початку епохи Unix. Час, який nanoTimeповертається, відносний (як правило, до початку програми) і був би нісенітницею, якби ви спробували перетворити його на побачення.
Дюни

так, але ви можете зберігати currentTimeilli та nano в якомусь статичному коді при запуску програми, а потім використовуйте їх як компенсації, щоб отримати точний нано з мілі, використовуючи подвійний var = currentTimeStart - nanoTimeStart + nanoTimeNow
tgkprog

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


4
Це мікро-орієнтир, і вам слід бути обережними, щоб довіряти отриманим результатам. Погляньте на stackoverflow.com/questions/504103/… .
Аксель

1
Цей орієнтир не є значущим, а ще краще, він показує, що операційна система під Java має значення. Я проводив один і той же показник в циклі десяток разів (переміщення ініціалізації "зараз" і "результат" з циклу), і у мене були симпатичні відмінності при кожному запуску: Дата (): 322 до 330; currentTimeMillis (): 319 до 322. На деяких інших запусках у мене була дата (): 312 до 318; currentTimeMillis (): від 324 до 335. Отже, IMHO вони досить рівноцінні, в реальних випадках (також дивлячись на джерело Date). JFYI, я використовував Java7 в Ubuntu.
Самписа

0

System.currentTimeMillis() це, очевидно, найшвидший, тому що це лише один метод виклику, і сміттєзбірник не потрібен.


14
Ваша відповідь не має значення, оскільки це лише підмножина попередньо затвердженої відповіді. Вам слід намагатися не відповідати таким чином, особливо не враховуючи, що це дуже старе запитання з уже наявною якісною відповіддю.
Nicklas Gnejs Eriksson

1
По-друге, сміттєзбірник так чи інакше не потрібен для короткочасних об'єктів в просторі Едему.
Niels Bech Nielsen
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.