System.cienTimeMillis () so với Ngày mới () so với Lịch.getInstance (). GetTime ()


238

Trong Java, hiệu suất và ý nghĩa tài nguyên của việc sử dụng là gì

System.currentTimeMillis() 

so với

new Date() 

so với

Calendar.getInstance().getTime()

Theo tôi hiểu, System.currentTimeMillis()là hiệu quả nhất. Tuy nhiên, trong hầu hết các ứng dụng, giá trị dài đó sẽ cần phải được chuyển đổi thành Ngày hoặc một số đối tượng tương tự để làm bất cứ điều gì có ý nghĩa với con người.

Câu trả lời:


241

System.currentTimeMillis()rõ ràng là hiệu quả nhất vì nó thậm chí không tạo ra một vật thể, nhưng new Date()thực sự chỉ là một lớp bọc mỏng dài, vì vậy nó không bị bỏ lại phía sau. Calendarmặt khác, tương đối chậm và rất phức tạp, vì nó phải đối phó với sự phức tạp đáng kể và tất cả những điều kỳ quặc vốn có của ngày và thời gian (năm nhuận, tiết kiệm ánh sáng ban ngày, múi giờ, v.v.).

Nói chung, chỉ nên xử lý các dấu thời gian hoặc Dateđối tượng dài trong ứng dụng của bạn và chỉ sử dụng Calendarkhi bạn thực sự cần thực hiện tính toán ngày / giờ hoặc định dạng ngày để hiển thị chúng cho người dùng. Nếu bạn phải làm nhiều việc này, sử dụng Joda Time có lẽ là một ý tưởng tốt, cho giao diện sạch hơn và hiệu suất tốt hơn.


2
Sự khác biệt giữa dấu thời gian và currentMillis là gì?
Pinkpanther

1
@pinkpanther: "dấu thời gian" thường được sử dụng để mô tả một số nguyên / dài mô tả một thời điểm khi được hiểu là giây hoặc mili giây kể từ khi "bắt đầu kỷ nguyên". Nói cách khác, currentTimeMillis () trả về dấu thời gian.
Michael Borgwardt

42

Nhìn vào JDK, hàm tạo trong cùng Calendar.getInstance()có cái này:

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

Vì vậy, nó đã tự động làm những gì bạn đề nghị. Trình xây dựng mặc định của ngày giữ điều này:

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

Vì vậy, thực sự không cần phải có thời gian hệ thống cụ thể trừ khi bạn muốn thực hiện một số phép toán với nó trước khi tạo đối tượng Lịch / Ngày với nó. Ngoài ra, tôi phải đề xuất joda-time để sử dụng thay thế cho các lớp lịch / ngày của riêng Java nếu mục đích của bạn là làm việc với các phép tính ngày rất nhiều.


22

Nếu bạn đang sử dụng một ngày thì tôi khuyên bạn nên sử dụng jodatime, http://joda-time.sourceforge.net/ . Sử dụng System.currentTimeMillis()cho các trường ngày nghe có vẻ là một ý tưởng rất tồi bởi vì bạn sẽ kết thúc với rất nhiều mã vô dụng.

Cả ngày và lịch đều rất nghiêm túc và Lịch chắc chắn là người biểu diễn tệ nhất trong tất cả.

Tôi khuyên bạn nên sử dụng System.currentTimeMillis()khi bạn thực sự hoạt động với mili giây, ví dụ như thế này

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

28
Tôi muốn bình luận về điều này bởi vì ví dụ của bạn chính xác là một trong những điều bạn KHÔNG nên sử dụng System.cienTimeMillis () cho; nó không phải là một nguồn đồng hồ đơn điệu, vì vậy bạn không thể tính toán thời gian trôi qua với nó một cách đáng tin cậy. Nếu đồng hồ hệ thống bị thay đổi trong khi mã bạn đang thực hiện, bạn sẽ nhận được kết quả kỳ lạ (ví dụ: phủ định). Thay vào đó, hãy sử dụng System.nanoTime (), đơn điệu nếu hệ thống cơ bản hỗ trợ nguồn đồng hồ như vậy (xem bug.java.com/bugdatabase/view_orms.do?orms_id=6458294 )
rem

Bản thân System.cienTimeMillis không bị ảnh hưởng bởi múi giờ. Thay đổi thời gian hệ thống sẽ ảnh hưởng đến System.nanotime theo cách tương tự như System.civerseTimeMillis
Viktor

12

Tôi thích sử dụng giá trị được trả về System.currentTimeMillis()cho tất cả các loại tính toán và chỉ sử dụng Calendarhoặc Datenếu tôi cần thực sự hiển thị một giá trị được đọc bởi con người. Điều này cũng sẽ ngăn 99% lỗi thời gian tiết kiệm ánh sáng ban ngày của bạn. :)


12

Trên máy tôi đã thử kiểm tra nó. Kết quả của tôi:

Lịch.getInstance (). GetTime () (* 1000000 lần) = 402ms
Ngày mới (). getTime (); (* 1000000 lần) = 18ms
System.cienTimeMillis () (* 1000000 lần) = 16ms

Đừng quên về GC (nếu bạn sử dụng Calendar.getInstance()hoặc new Date())


1
tự hỏi liệu sẽ có sự khác biệt nào không nếu nhiều luồng gọi giống nhau ở giữa quá trình xử lý khác
tgkprog 18/12/13

7

Tùy thuộc vào ứng dụng của bạn, bạn có thể muốn xem xét sử dụng System.nanoTime()thay thế.


Tại sao, câu hỏi của anh là về tài nguyên và hiệu suất, nanoTime () sử dụng nhiều tài nguyên hơn
WolfmanDragon

Tôi đã đề cập đến nó bởi vì đó là một lựa chọn mà không ai khác đề xuất. Các poster không chỉ định một nền tảng. Lỗi SDN 6876279 gợi ý rằng currentTimeMillis () và nanoTime () giống nhau trong một số phiên bản JDK. Người đăng cũng không nêu rõ nhu cầu chính xác của họ, trong đó danh sách ban đầu có thể không đầy đủ.
MykennaC

4
Càng muộn, tất cả các ví dụ trong câu hỏi đều có một khái niệm tuyệt đối về thời gian là gì. 1.348.770.313.071 millis kể từ khi bắt đầu kỷ nguyên Unix. Thời gian nanoTimetrả về là tương đối (thường là khi bắt đầu chương trình) và sẽ vô nghĩa nếu bạn cố gắng biến nó thành một ngày.
Cồn cát

có nhưng bạn có thể lưu trữ currentTimeilli và nano trong một số mã tĩnh khi bắt đầu chương trình, sau đó sử dụng chúng làm phần bù để lấy nano chính xác từ milli bằng cách sử dụng var = currentTimeStart - nanoTimeStart + nanoTimeNow
tgkprog 18/12/13

3

Tôi đã thử điều này:

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

Và kết quả là:

Ngày (): 199

currentTimeMillis (): 3


4
Đây là một điểm chuẩn vi mô và bạn nên cẩn thận để tin tưởng vào kết quả bạn nhận được. Có một cái nhìn về stackoverflow.com/questions/504103/ .
Axel

1
Điểm chuẩn này không có ý nghĩa hoặc tốt hơn, nó cho thấy hệ điều hành theo Java có vấn đề. Tôi đã chạy cùng một điểm chuẩn trong một vòng lặp hàng chục lần (di chuyển khởi tạo "bây giờ" và "kết quả" ra khỏi vòng lặp) và tôi có những khác biệt dễ thương ở mỗi lần chạy: Ngày (): 322 đến 330; currentTimeMillis (): 319 đến 322. Trong một số lần chạy khác, tôi có Date (): 312 đến 318; currentTimeMillis (): 324 đến 335. Vì vậy, IMHO chúng tương đối giống nhau, trên các trường hợp thực tế (cũng nhìn vào nguồn của Ngày). JFYI, tôi đã sử dụng Java7 trên Ubuntu.
Sampisa

0

System.currentTimeMillis() rõ ràng là nhanh nhất vì đó chỉ là một cuộc gọi phương thức và không yêu cầu trình thu gom rác.


14
Câu trả lời của bạn không có giá trị vì nó chỉ là một tập hợp con của câu trả lời đã được phê duyệt trước đó. Bạn nên cố gắng không trả lời theo cách này, đặc biệt là không coi đó là một câu hỏi rất cũ với câu trả lời chất lượng đã có sẵn.
Nicklas Gnejs Eriksson

1
Thứ hai, dù sao thì cũng không cần bộ thu gom rác cho các đối tượng ngắn hạn trong không gian Eden.
Niels Bech Nielsen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.