System.currentTimeMillis() vs. new Date() vs. Calendar.getInstance().getTime()

Posted

技术标签:

【中文标题】System.currentTimeMillis() vs. new Date() vs. Calendar.getInstance().getTime()【英文标题】: 【发布时间】:2010-09-26 22:54:47 【问题描述】:

在 Java 中,使用对性能和资源的影响是什么

System.currentTimeMillis() 

对比

new Date() 

对比

Calendar.getInstance().getTime()

据我了解,System.currentTimeMillis() 是最有效的。但是,在大多数应用程序中,需要将 long 值转换为 Date 或一些类似的对象才能执行对人类有意义的任何事情。

【问题讨论】:

【参考方案1】:

System.currentTimeMillis() 显然是最高效的,因为它甚至不创建对象,但new Date() 实际上只是一个大约很长的薄包装器,所以它也不甘落后。另一方面,Calendar 相对较慢且非常复杂,因为它必须处理日期和时间(闰年、夏令时、时区等)所固有的相当复杂和所有奇怪的问题。

通常最好只处理应用程序中的长时间戳Date 对象,并且仅在您实际需要执行日期/时间计算或格式化日期以向用户显示它们时才使用Calendar .如果你必须做很多这样的事情,使用Joda Time 可能是个好主意,因为它的界面更简洁,性能更好。

【讨论】:

timestamp和currentMillis有什么区别? @pinkpanther:“timestamp”通常用于描述一个整数/长整数,当解释为“纪元开始”以来的秒数或毫秒时,它描述了一个时间点。换句话说,currentTimeMillis() 返回一个时间戳。【参考方案2】:

查看 JDK,Calendar.getInstance() 的最里面的构造函数是这样的:

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

所以它已经自动执行您的建议。 Date 的默认构造函数包含以下内容:

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

因此,除非您想在使用它创建日历/日期对象之前对其进行一些数学运算,否则实际上不需要专门获取系统时间。如果您的目的是大量使用日期计算,我还必须推荐 joda-time 来替代 Java 自己的日历/日期类。

【讨论】:

【参考方案3】:

如果您使用日期,那么我强烈建议您使用 jodatime,http://joda-time.sourceforge.net/。将System.currentTimeMillis() 用于日期的字段听起来是个非常糟糕的主意,因为你最终会得到很多无用的代码。

日期和日历都非常糟糕,日历绝对是其中表现最差的。

我建议您在实际使用毫秒操作时使用System.currentTimeMillis(),例如像这样

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

【讨论】:

我想对此发表评论,因为您的示例正是您应该使用 System.currentTimeMillis() 的事情之一;它不是一个单调的时钟源,所以你不能用它可靠地计算经过的时间。如果在您正在计时的代码正在执行时更改系统时钟,您将得到奇怪的(例如否定的)结果。而是使用 System.nanoTime(),它单调如果底层系统支持这样的时钟源(参见bugs.java.com/bugdatabase/view_bug.do?bug_id=6458294) System.currentTimeMillis 本身不受时区影响。更改系统时间会像 System.currentTimeMillis 一样影响 System.nanotime @Viktor 不正确,nanoTime() 是一个始终递增的计数器,它永远不会返回小于上次在此 JVM 实例中调用的值。 currentTimeMillis() 可以返回小于上次调用时间的值,因为系统时间正在更改,例如NTP 时钟同步。【参考方案4】:

在我的机器上我尝试检查它。我的结果:

Calendar.getInstance().getTime() (*1000000 次) = 402ms 新日期().getTime(); (*1000000 次) = 18ms System.currentTimeMillis() (*1000000 次) = 16ms

不要忘记 GC(如果您使用 Calendar.getInstance()new Date()

【讨论】:

想知道如果许多线程在其他处理之间调用相同的会有什么不同【参考方案5】:

我更喜欢将System.currentTimeMillis() 返回的值用于各种计算,并且仅在我需要真正显示人类读取的值时才使用CalendarDate。这也将防止 99% 的夏令时错误。 :)

【讨论】:

【参考方案6】:

根据您的应用程序,您可能需要考虑改用System.nanoTime()

【讨论】:

为什么,他的问题是关于资源和性能,nanoTime() 使用更多资源 我提到它是因为这是一个没有其他人建议的选项。海报没有指定平台。 SDN 错误 6876279 表明 currentTimeMillis() 和 nanoTime() 在某些 JDK 版本中的使用大致相同。发布者也没有具体说明他们的准确性需求,原始列表可能不足以满足这些需求。 这可能很晚,但问题中的所有示例都有一个绝对的时间概念,例如。自 Unix 纪元开始以来的 1,348,770,313,071 毫秒。 nanoTime 返回的时间是相对的(通常是程序开始的时间),如果你试图把它变成一个日期,那将是无稽之谈。 是的,但是您可以在程序启动时将 currentTimeilli 和 nano 存储在一些静态代码中,然后使用它们作为偏移量,使用 double var = currentTimeStart - nanoTimeStart + nanoTimeNow 从 milli 获取准确的 nano【参考方案7】:

我试过了:

        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

【讨论】:

这是一个微基准测试,你应该小心相信你得到的结果。看看***.com/questions/504103/…。 这个基准没有意义,或者更好,它表明Java下的操作系统确实很重要。我在循环中运行了十多次相同的基准测试(将“现在”和“结果”的初始化移出循环),每次运行我都有可爱的差异: Date() : 322 to 330; currentTimeMillis():319 到 322。在其他一些运行中,我有 Date():312 到 318; currentTimeMillis():324 到 335。所以,恕我直言,在实际情况下它们是相当的(也查看日期的来源)。 JFYI,我在 Ubuntu 上使用过 Java7。【参考方案8】:

System.currentTimeMillis() 显然是最快的,因为它只是一个方法调用,不需要垃圾收集器。

【讨论】:

您的答案没有任何价值,因为它只是之前批准的答案的一个子集。您应该尽量不要以这种方式回答,尤其不要考虑到这是一个非常古老的问题,并且已经存在高质量的答案。 其次,Eden 空间中的短期对象无论如何都不需要垃圾收集器。

以上是关于System.currentTimeMillis() vs. new Date() vs. Calendar.getInstance().getTime()的主要内容,如果未能解决你的问题,请参考以下文章

System.currentTimeMillis() 是不是返回 UTC 时间?

给定日期的 System.currentTimeMillis()? [复制]

System.nanoTime()和System.currentTimeMillis()性能问题

System.currentTimeMillis()

System.currentTimeMillis() uptimeMillis() elapsedRealtime() 区别

System.currentTimeMillis()和new Date().getTime()比较