System.currentTimeMillis () เทียบกับวันที่ใหม่ () กับ Calendar.getInstance (). getTime ()


239

ใน Java ประสิทธิภาพการทำงานและทรัพยากรของการใช้คืออะไร

System.currentTimeMillis() 

เมื่อเทียบกับ

new Date() 

เมื่อเทียบกับ

Calendar.getInstance().getTime()

เท่าที่ฉันเข้าใจมันSystem.currentTimeMillis()เป็นสิ่งที่มีประสิทธิภาพมากที่สุด อย่างไรก็ตามในแอปพลิเคชั่นส่วนใหญ่ค่าที่มีความยาวนั้นจะต้องถูกแปลงเป็น Date หรือวัตถุที่คล้ายกันเพื่อทำสิ่งที่มีความหมายต่อมนุษย์

คำตอบ:


242

System.currentTimeMillis()เห็นได้ชัดว่ามีประสิทธิภาพมากที่สุดเพราะมันไม่ได้สร้างวัตถุ แต่new Date()เป็นเพียงเสื้อคลุมบาง ๆ ที่มีความยาวดังนั้นมันจึงไม่อยู่ด้านหลัง Calendarในทางกลับกันค่อนข้างช้าและซับซ้อนมากเนื่องจากต้องจัดการกับความซับซ้อนและสิ่งแปลกประหลาดทั้งหมดที่มีอยู่ในวันที่และเวลา (ปีอธิกสุรทินออมทรัพย์เขตเวลา ฯลฯ )

โดยทั่วไปแล้วเป็นความคิดที่ดีที่จะจัดการกับการประทับเวลาที่ยาวนานหรือDateวัตถุภายในแอปพลิเคชันของคุณและใช้เฉพาะCalendarเมื่อคุณจำเป็นต้องทำการคำนวณวันที่ / เวลาหรือจัดรูปแบบวันที่เพื่อแสดงให้ผู้ใช้เห็น หากคุณต้องทำสิ่งนี้มากการใช้Joda Timeน่าจะเป็นความคิดที่ดีสำหรับอินเทอร์เฟซที่สะอาดตาและประสิทธิภาพที่ดีขึ้น


2
ความแตกต่างระหว่างการประทับเวลาและ currentMillis คืออะไร?
pinkpanther

1
@pinkpanther: "timestamp" โดยปกติจะใช้เพื่ออธิบายจำนวนเต็ม / ยาวที่อธิบายจุดในเวลาเมื่อตีความว่าเป็นวินาทีหรือมิลลิวินาทีนับตั้งแต่ "เริ่มต้นยุค" อีกนัยหนึ่ง currentTimeMillis () จะคืนค่าการประทับเวลา
Michael Borgwardt

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

System.currentTimeMillis ตัวเองไม่ได้รับผลกระทบจากเขตเวลา การเปลี่ยนเวลาของระบบจะส่งผลต่อ System.nanotime ในลักษณะเดียวกับ System.currentTimeMillis
Viktor

12

ฉันชอบใช้ค่าที่ส่งคืนโดยSystem.currentTimeMillis()สำหรับการคำนวณทุกประเภทและใช้เฉพาะCalendarหรือDateถ้าฉันต้องการแสดงค่าที่มนุษย์อ่าน สิ่งนี้จะป้องกัน 99% ของข้อบกพร่องในการปรับบันทึกเวลาตามฤดูกาลของคุณ :)


12

บนเครื่องของฉันฉันลองตรวจสอบดู ผลลัพธ์ของฉัน:

Calendar.getInstance (). getTime () (* 1000000 ครั้ง) = 402ms
ใหม่วันที่ (). getTime (); (* 1000000 ครั้ง) = 18ms
System.currentTimeMillis () (* 1000000 ครั้ง) = 16ms

อย่าลืมเกี่ยวกับ GC (ถ้าคุณใช้Calendar.getInstance()หรือnew Date())


1
สงสัยว่าจะมีความแตกต่างหรือไม่ถ้ามีหลายเธรดที่เรียกว่าเหมือนกันระหว่างการประมวลผลอื่น ๆ
tgkprog

7

คุณอาจต้องพิจารณาใช้System.nanoTime()แทนทั้งนี้ขึ้นอยู่กับแอปพลิเคชันของคุณ


ทำไมคำถามของเขาเกี่ยวกับทรัพยากรและประสิทธิภาพ nanoTime () ใช้ทรัพยากรมากขึ้น
WolfmanDragon

ฉันพูดถึงมันเพราะมันเป็นตัวเลือกที่ไม่มีใครแนะนำ โปสเตอร์ไม่ได้ระบุแพลตฟอร์ม ข้อผิดพลาด SDN 6876279 แสดงให้เห็นว่า currentTimeMillis () และ nanoTime () ใช้เวลาเหมือนกันในบางรุ่น JDK ผู้โพสต์ยังไม่ได้ระบุความต้องการความแม่นยำของพวกเขาซึ่งรายการดั้งเดิมอาจไม่เพียงพอ
MykennaC

4
ล่าช้าเนื่องจากอาจเป็นไปได้ตัวอย่างทั้งหมดในคำถามนี้มีความคิดที่แน่นอนว่าเวลาเท่าไหร่เช่น 1,348,770,313,071 millis ตั้งแต่จุดเริ่มต้นของยุค Unix เวลาที่nanoTimeส่งคืนนั้นสัมพันธ์กัน (โดยปกติจะเป็นจุดเริ่มต้นของโปรแกรม) และจะไร้สาระหากคุณพยายามเปลี่ยนให้เป็นวันที่
Dunes

ใช่ แต่คุณสามารถเก็บ currentTimeilli และ nano ในโค้ดแบบสแตติกเมื่อเริ่มโปรแกรมจากนั้นใช้ offsets เพื่อรับ nano ที่ถูกต้องจาก milli โดยใช้ double 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/… .
Axel

1
มาตรฐานนี้ไม่สำคัญหรือดีกว่ามันแสดงให้เห็นว่าระบบปฏิบัติการภายใต้ Java มีความสำคัญ ฉันวิ่งเกณฑ์มาตรฐานเดียวกันในโหลวนครั้ง (การเริ่มต้นการย้ายของ "ตอนนี้" และ "ผล" ออกจากวง) และฉันมีความแตกต่างที่น่ารักในแต่ละวิ่ง: วันที่ (): 322 ถึง 330; currentTimeMillis (): 319 ถึง 322 ในบางรันฉันมีวันที่ (): 312 ถึง 318; currentTimeMillis (): 324 ถึง 335 ดังนั้น IMHO จึงเทียบเท่ากันในกรณีจริง (ดูที่แหล่งที่มาของวันที่) JFYI ฉันใช้ Java7 บน Ubuntu
Sampisa

0

System.currentTimeMillis() เห็นได้ชัดว่าเร็วที่สุดเพราะเป็นวิธีการเดียวที่เรียกใช้และไม่จำเป็นต้องมีตัวรวบรวมขยะ


14
คำตอบของคุณไม่มีคุณค่าเนื่องจากเป็นเพียงส่วนย่อยของคำตอบที่ได้รับอนุมัติก่อนหน้านี้ คุณควรพยายามที่จะไม่ตอบคำถามในลักษณะนี้โดยเฉพาะอย่างยิ่งการพิจารณาว่าเป็นคำถามที่เก่ามากที่มีคำตอบคุณภาพอยู่แล้ว
Nicklas Gnejs Eriksson

1
ประการที่สองไม่จำเป็นต้องมีตัวรวบรวมขยะสำหรับวัตถุระยะสั้นในพื้นที่เอเดน
Niels Bech Nielsen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.