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()
返回的值用于各种计算,并且仅在我需要真正显示人类读取的值时才使用Calendar
或Date
。这也将防止 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() uptimeMillis() elapsedRealtime() 区别