System.currentTimeMillis () ile new Date () vs. Calendar.getInstance (). GetTime ()


239

Java'da, kullanmanın performans ve kaynak etkileri nelerdir?

System.currentTimeMillis() 

vs.

new Date() 

vs.

Calendar.getInstance().getTime()

Anladığım kadarıyla System.currentTimeMillis()en verimli olanı. Bununla birlikte, çoğu uygulamada, insanlar için anlamlı herhangi bir şey yapmak için bu uzun değerin bir Tarihe veya benzer bir nesneye dönüştürülmesi gerekir.

Yanıtlar:


242

System.currentTimeMillis()Açıkçası en etkili olanıdır, çünkü bir nesne bile yaratmaz, ama new Date()gerçekten uzun bir süre için ince bir sargıdır, bu yüzden çok geride değildir. CalendarÖte yandan, nispeten yavaş ve çok karmaşıktır, çünkü tarihler ve saatlerin (artık yıllar, gün ışığından yararlanma, zaman dilimleri vb.) İçinde bulunan oldukça karmaşık ve tüm tuhaflıklarla uğraşmak zorundadır.

Genellikle Dateuygulamanızdaki uzun zaman damgaları veya nesnelerle ilgilenmek ve yalnızca Calendartarih / saat hesaplamaları yapmanız gerektiğinde veya bunları kullanıcıya görüntülemek için tarihleri ​​biçimlendirmek için kullanmak iyi bir fikirdir . Bunların çoğunu yapmanız gerekiyorsa, daha temiz bir arayüz ve daha iyi performans için Joda Time'ı kullanmak iyi bir fikir olabilir.


2
Timestamp ve currentMillis arasındaki fark nedir?
pinkpanther

1
@pinkpanther: "zaman damgası" normalde bir "dönem başlangıcı" ndan bu yana saniye veya milisaniye olarak yorumlandığında zaman noktasını tanımlayan bir tamsayıyı / uzunluğu tanımlamak için kullanılır. Başka bir deyişle, currentTimeMillis () bir zaman damgası döndürür.
Michael Borgwardt

43

JDK'ya bakıldığında, en içteki kurucu şuna Calendar.getInstance()sahiptir:

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

böylece önerilerinizi zaten otomatik olarak yapar. Tarihin varsayılan kurucusu şunları tutar:

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

Dolayısıyla, Takvim / Tarih nesnenizi onunla oluşturmadan önce onunla biraz matematik yapmak istemiyorsanız, sistem zamanını özellikle almanıza gerek yoktur. Ayrıca , amacınız tarih hesaplamaları ile çok çalışmaksa, Java'nın kendi takvim / tarih sınıflarının yerini almak için joda-time'ı tavsiye etmem gerekir .


22

Bir tarih kullanıyorsanız, jodatime, http://joda-time.sourceforge.net/ kullanmanızı şiddetle tavsiye ederim . Kullanılması System.currentTimeMillis()alanlar için olan çok kötü bir fikir gibi tarihleri sesler kullanışsız koda bir sürü bitireceğiz çünkü.

Hem tarih hem de takvim ciddi bir şekilde kuşatıldı ve Takvim kesinlikle hepsinin en kötü performansı.

System.currentTimeMillis()Gerçekten milisaniye ile çalışırken kullanmanızı öneririm , örneğin böyle

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

28
Ben senin örneğin tam olarak gereken şeylerden biri olduğu için bu konuda yorum istedi DEĞİL için System.currentTimeMillis () kullanın; tekdüze bir saat kaynağı değildir, bu nedenle geçen zamanı güvenilir bir şekilde hesaplayamazsınız. Zamanlama yaptığınız kod yürütülürken sistem saati değiştirilirse, garip (örneğin negatif) sonuçlar alırsınız. Stead kullanım System.nanoTime (), In olduğunu monoton eğer altta yatan sistem desteklerin böyle bir saat kaynağı (bkz bugs.java.com/bugdatabase/view_bug.do?bug_id=6458294 )
rem

System.currentTimeMillis'in kendisi saat diliminden etkilenmez. Sistem saatini değiştirmek System.nanotime'ı System.currentTimeMillis ile aynı şekilde etkiler
Viktor

12

System.currentTimeMillis()Her türlü hesaplama için döndürülen değeri kullanmayı tercih ediyorum ve sadece Calendarveya Dateinsanlar tarafından okunan bir değeri gerçekten göstermem gerekiyorsa kullanın. Bu aynı zamanda gün ışığından yararlanma saati hatalarınızın% 99'unu önleyecektir. :)


12

Makinemde kontrol etmeye çalıştım. Benim sonucum:

Calendar.getInstance (). GetTime () (* 1000000 kez) = 402 ms
yeni Tarih (). getTime (); (* 1000000 kez) = 18 ms
System.currentTimeMillis () (* 1000000 kez) = 16 ms

GC'yi unutmayın ( Calendar.getInstance()veya kullanıyorsanız new Date())


1
birçok iş parçacığı diğer işleme arasında aynı çağırırsa herhangi bir fark olup olmadığını merak
tgkprog

7

Uygulamanıza bağlı olarak, System.nanoTime()bunun yerine kullanmayı düşünebilirsiniz .


Neden, sorusu kaynaklar ve performansla ilgiliydi, nanoTime () daha fazla kaynak kullanıyor
WolfmanDragon

Bundan bahsettim çünkü başka kimsenin önermediği bir seçenek. Poster bir platform belirtmedi. SDN hatası 6876279, currentTimeMillis () ve nanoTime () öğesinin bazı JDK sürümlerinde yaklaşık aynı şeyi aldığını gösterir. Poster ayrıca orijinal listenin yetersiz olabileceği doğruluk ihtiyaçlarını da belirtmedi.
MykennaC

4
Bu kadar geç olduğunda, sorudaki tüm örneklerin saatin kaç olduğu konusunda mutlak bir fikri vardır. Unix döneminin başlangıcından bu yana 1.348.770.313.071 milis. Dönen süre nanoTimegörecelidir (genellikle programın başlangıcına kadar) ve bir tarihe dönüştürmeyi denerseniz saçma olur.
Dunes

nanoTimeStart + nanoTimeNow - evet ama o zaman = currentTimeStart çift var kullanarak Millî'den doğru bir nano almak için uzaklıklar olarak kullanmanıza program başlangıcında bazı statik kodunda currentTimeilli ve nano depolayabilir
tgkprog

3

Bunu denedim:

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

Ve sonuç şuydu:

Tarih (): 199

currentTimeMillis (): 3


4
Bu bir mikro ölçüttür ve elde ettiğiniz sonuçlara güvenmeye dikkat etmelisiniz. Stackoverflow.com/questions/504103/… adresine bir göz atın .
Axel

1
Bu kıyaslama anlamlı ya da daha iyi değildir, Java altındaki işletim sisteminin önemli olduğunu gösterir. Aynı ölçütü düzinelerce döngüde çalıştırdım ("şimdi" ve "sonuç" un döngüden çıkarılması) ve her çalıştırmada sevimli farklılıklar yaşadım: Tarih (): 322 ila 330; currentTimeMillis (): 319 ila 322. Diğer bazı çalışmalarda Date (): 312 ila 318; currentTimeMillis (): 324 ila 335. Yani, IMHO gerçek durumlarda oldukça eşdeğerdir (ayrıca Tarih kaynağına da bakar). JFYI, Ubuntu'da Java7 kullandım.
Sampisa

0

System.currentTimeMillis() Açıkçası en hızlısıdır çünkü tek bir yöntem çağrısıdır ve çöp toplayıcı gerekmez.


14
Daha önce onaylanmış cevabın sadece bir alt kümesi olması nedeniyle cevabınızın bir değeri yoktur. Bu şekilde cevap vermemeye çalışmalısınız, özellikle de mevcut bir kalite cevabı ile çok eski bir soru olduğunu düşünmemelisiniz.
Nicklas Gnejs Eriksson

1
İkincisi, yine de Eden alanındaki kısa süreli nesneler için çöp toplayıcı gerekli değildir.
Niels Bech Nielsen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.