System.currentTimeMillis () vs Date baru () vs. Calendar.getInstance (). GetTime ()

239

Di Jawa, apa implikasi kinerja dan sumber daya yang digunakan

System.currentTimeMillis() 

vs.

new Date() 

vs.

Calendar.getInstance().getTime()

Seperti yang saya pahami, System.currentTimeMillis()adalah yang paling efisien. Namun, di sebagian besar aplikasi, nilai panjang itu perlu dikonversi menjadi Date atau objek serupa untuk melakukan sesuatu yang berarti bagi manusia.

Vihung
sumber

Jawaban:

242

System.currentTimeMillis()Jelas yang paling efisien karena bahkan tidak membuat objek, tetapi new Date()sebenarnya hanya pembungkus tipis tentang panjang, jadi tidak jauh di belakang. Calendar, di sisi lain, relatif lambat dan sangat kompleks, karena harus berurusan dengan kompleksitas yang sangat dan semua keanehan yang melekat pada tanggal dan waktu (tahun kabisat, penghematan siang hari, zona waktu, dll.).

Biasanya merupakan ide bagus untuk hanya berurusan dengan cap waktu yang panjang atau Dateobjek dalam aplikasi Anda, dan hanya digunakan Calendarketika Anda benar-benar perlu melakukan perhitungan tanggal / waktu, atau memformat tanggal untuk menampilkannya kepada pengguna. Jika Anda harus melakukan banyak hal, menggunakan Joda Time mungkin ide yang bagus, untuk antarmuka yang lebih bersih dan kinerja yang lebih baik.

Michael Borgwardt
sumber
2
Apa perbedaan antara timestamp dan currentMillis?
pinkpanther
1
@pinkpanther: "timestamp" biasanya digunakan untuk menggambarkan bilangan bulat / panjang yang menggambarkan suatu titik waktu ketika ditafsirkan sebagai detik atau milidetik sejak "awal zaman". Dengan kata lain, currentTimeMillis () mengembalikan timestamp.
Michael Borgwardt
43

Melihat JDK, konstruktor terdalam untuk Calendar.getInstance()memiliki ini:

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

jadi sudah otomatis melakukan apa yang Anda sarankan. Konstruktor default Date memegang ini:

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

Jadi benar-benar tidak perlu untuk mendapatkan waktu sistem khusus kecuali Anda ingin melakukan matematika dengannya sebelum membuat objek Kalender / Tanggal Anda dengannya. Juga saya harus merekomendasikan joda-waktu untuk digunakan sebagai pengganti untuk kalender / tanggal kelas Java sendiri jika tujuan Anda adalah untuk bekerja dengan banyak perhitungan tanggal.

Esko
sumber
22

Jika Anda MENGGUNAKAN tanggal maka saya sangat menyarankan Anda menggunakan jodatime, http://joda-time.sourceforge.net/ . Menggunakan System.currentTimeMillis()untuk bidang yang adalah tanggal suara seperti ide yang sangat buruk karena Anda akan berakhir dengan banyak kode berguna.

Baik tanggal dan kalender benar-benar kacau, dan Kalender jelas merupakan pemain terburuk dari semuanya.

Saya menyarankan Anda untuk menggunakan System.currentTimeMillis()ketika Anda benar-benar beroperasi dengan milidetik, misalnya seperti ini

 long start = System.currentTimeMillis();
    .... do something ...
 long elapsed = System.currentTimeMillis() -start;
krosenvold
sumber
28
Saya ingin mengomentari ini karena contoh Anda adalah salah satu hal yang seharusnya TIDAK Anda gunakan System.currentTimeMillis () untuk; ini bukan sumber jam monoton, jadi Anda tidak dapat menghitung waktu yang berlalu dengan andal. Jika jam sistem diubah saat kode waktu Anda dijalankan, Anda akan mendapatkan hasil yang aneh (misalnya negatif). Dalam penggunaan manfaat System.nanoTime (), yang merupakan monoton jika dukungan sistem yang mendasari seperti sumber jam (lihat bugs.java.com/bugdatabase/view_bug.do?bug_id=6458294 )
rem
System.currentTimeMillis sendiri tidak terpengaruh oleh zona waktu. Mengubah waktu sistem akan memengaruhi System.nanotime dengan cara yang sama dengan System.currentTimeMillis
Viktor
12

Saya lebih suka menggunakan nilai yang dikembalikan oleh System.currentTimeMillis()untuk semua jenis perhitungan dan hanya menggunakan Calendaratau Datejika saya harus benar-benar menampilkan nilai yang dibaca oleh manusia. Ini juga akan mencegah 99% bug di siang hari Anda. :)

Bombe
sumber
12

Di mesin saya, saya mencoba memeriksanya. Hasil saya:

Calendar.getInstance (). GetTime () (* 1000000 kali) = 402ms
Tanggal baru (). getTime (); (* 1000000 kali) = 18ms
System.currentTimeMillis () (* 1000000 kali) = 16ms

Jangan lupa tentang GC (jika Anda menggunakan Calendar.getInstance()atau new Date())

Puzirki
sumber
1
bertanya-tanya apakah akan ada perbedaan jika banyak utas menyebut hal yang sama di antara pemrosesan lainnya
tgkprog
7

Tergantung pada aplikasi Anda, Anda mungkin ingin mempertimbangkan untuk menggunakannya System.nanoTime().

MykennaC
sumber
Mengapa, pertanyaannya adalah tentang sumber daya dan kinerja, nanoTime () menggunakan lebih banyak sumber daya
WolfmanDragon
Saya menyebutkannya karena itu pilihan yang tidak disarankan orang lain. Poster tidak menentukan platform. Bug SDN 6876279 menyarankan bahwa currentTimeMillis () dan nanoTime () memiliki jumlah yang hampir sama di beberapa versi JDK. Poster itu juga tidak merinci kebutuhan akurasi mereka, yang daftar aslinya mungkin tidak memadai.
MykennaC
4
Terlambat seperti ini, semua contoh dalam pertanyaan memiliki gagasan absolut tentang jam berapa saat itu misalnya. 1.348.770.313.071 mili sejak dimulainya zaman Unix. Waktu yang nanoTimedikembalikan relatif (biasanya pada awal program) dan akan menjadi omong kosong jika Anda mencoba mengubahnya menjadi tanggal.
Bukit pasir
ya tetapi Anda dapat menyimpan currentTimeilli dan nano dalam beberapa kode statis pada awal program, kemudian gunakan itu sebagai offset untuk mendapatkan nano yang akurat dari mili menggunakan var ganda = currentTimeStart - nanoTimeStart + nanoTimeNow
tgkprog
3

Saya mencoba ini:

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

Dan hasilnya adalah:

Tanggal (): 199

currentTimeMillis (): 3

wiji
sumber
4
Ini adalah tolok ukur mikro dan Anda harus berhati-hati untuk mempercayai hasil yang Anda dapatkan. Lihatlah stackoverflow.com/questions/504103/… .
Axel
1
Benchmark ini tidak signifikan, atau lebih baik, ini menunjukkan bahwa sistem operasi di Jawa itu penting. Saya menjalankan patokan yang sama dalam satu lusin kali loop (memindahkan inisialisasi "sekarang" dan "hasil" keluar dari loop), dan saya memiliki perbedaan yang lucu di setiap putaran: Date (): 322 hingga 330; currentTimeMillis (): 319 hingga 322. Pada beberapa proses lainnya saya memiliki Date (): 312 hingga 318; currentTimeMillis (): 324 hingga 335. Jadi, IMHO mereka cukup setara, pada kasus nyata (juga melihat sumber Date). JFYI, saya menggunakan Java7 di Ubuntu.
Sampisa
0

System.currentTimeMillis() jelas yang tercepat karena hanya satu metode panggilan dan tidak ada pengumpul sampah yang diperlukan.

Ramon
sumber
14
Jawaban Anda tidak memiliki nilai karena itu hanya sebagian dari jawaban yang disetujui sebelumnya. Anda harus berusaha untuk tidak menjawab dengan cara ini, terutama karena tidak menganggapnya sebagai pertanyaan yang sangat lama dengan jawaban kualitas yang sudah ada.
Nicklas Gnejs Eriksson
1
Kedua, pengumpul sampah tidak diperlukan untuk objek jangka pendek di ruang Eden.
Niels Bech Nielsen