java - 最有效地从文件中写入和读取 LocalDateTime

标签 java java-8 java-time

LocalDateTime 实例写入文件,然后从文件中读取它并将其转换回 LocalDateTime 对象的最快方法是什么?

我曾经保存毫秒,然后将其转换为 Date 对象。它看起来相当快,但现在我正在处理 Java 8 的 LocalDateTime,并且不清楚从文件中保存和检索它的最有效方法是什么。

我认为使用 DateTimeFormater 不是一个好主意,因为它需要更多资源将其转换为 String,然后解析 String .

时区不相关。

最佳答案

如果你想保存毫秒并且时区并不重要,你可以使用java.time.Instant类 - 仅包含 LocalDateTime无法获取毫秒,因为此类没有时区/偏移信息。

// get the current date
Instant instant = Instant.now();

// get milliseconds (equivalent to java.util.Date.getTime())
long millis = instant.toEpochMilli();

// get Instant from milliseconds
Instant instant = Instant.ofEpochMilli(millis);
<小时/>

如果您有 LocalDateTime不过,您可以轻松地将其转换为 Instant :

LocalDateTime d = LocalDateTime.now();
Instant instant = d.atOffset(ZoneOffset.UTC).toInstant();

这段代码显然假设 LocalDateTime 中的值对应于 UTC 日期和时间。转换Instant返回LocalDateTime :

LocalDateTime d = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
<小时/>

PS:您是否测量过系统的性能来了解“快”是否真的是一个问题?无论如何,我正在以“标准”方式做事(基于 API 提供的最直接的方式),这是您想要的吗?

也许您可以认为创建 Instant作为“中间”对象会使事情变得不那么“快”(但无论如何你都需要测量它)。如果是这种情况,您可以从 LocalDateTime 获取毫秒。直接(假设它对应于 UTC 中的日期和时间):

// get the current date
LocalDateTime d = LocalDateTime.now();
// get milliseconds value
long millis = d.toEpochSecond(ZoneOffset.UTC) * 1000 + d.get(ChronoField.MILLI_OF_SECOND);

// get LocalDateTime from millis
LocalDateTime d = LocalDateTime.ofEpochSecond(millis / 1000, (int) (millis % 1000) * 1000000, ZoneOffset.UTC);

需要注意的是java.time类具有纳秒精度,因此获取毫秒会使您失去此精度。

如果您不想失去纳秒精度并且不一定需要使用毫秒值,则可以存储 2 个不同的数字(纪元日纳秒日):

// get the current date
LocalDateTime d = LocalDateTime.now();

// get values from LocalDateTime
long epochDay = d.toLocalDate().toEpochDay();
long nanoOfDay = d.toLocalTime().toNanoOfDay();
// save both values to file

// retrieve the LocalDateTime from the values
LocalDateTime d = LocalDateTime.of(LocalDate.ofEpochDay(epochDay), LocalTime.ofNanoOfDay(nanoOfDay));

这不需要转换为 UTC,但需要 2 个数字而不是 1 个。您可能认为创建 LocalDate和一个 LocalTime使事情变慢,但这两个对象总是LocalDateTime 在内部创建(在所有情况下)。

不过,不确定所有这些数学运算是否比使用 Instant 足够“快”。 。这是一个测试问题,看看哪一个最适合您的情况。

但对我来说,在清晰度和代码易于维护方面最“有效”的是使用 Instant (或使用纪元日纳日的最后一种方法)。除非您要处理数百万条记录,否则我不确定这是否真的会成为性能问题。

<小时/>

我做了一个简单的测试(每个案例运行超过 1000 万次),最后一种方法(使用epoch daynano of day)似乎是最快的。但相差不到1秒。仅通过运行 20 亿次,我就有了 20 秒的差异,因此,如果您要处理这么多记录,也许这是值得的。

关于其他资源(内存使用、CPU、I/O),我没有检查。但无论如何,性能问题对于每个环境来说都是非常具体的:根据系统的设计方式、系统的部件/模块/组件如何相互交互以及许多其他因素,在每种情况下可能会遇到不同的瓶颈。

最后,您必须测试每种方法并查看哪种方法在您的系统中表现最佳。或者您可以得出结论,它不会产生显着差异(对于记录少于几百万条的情况,也许不会 - 但您只有在对其进行基准测试后才会知道)。

关于java - 最有效地从文件中写入和读取 LocalDateTime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45091813/

相关文章:

java - 当使用 lambda 表达式而不是匿名内部类时,Spring 无法确定泛型类型

java - SimpleDateFormat - 格式 - 九月 - JDK16

java - 我可以在 Jsoup 中的所有 html text() 元素之间包含空格吗

Java 从具有多个条件的列表中搜索子列表

java - 如何从 resultResult 中获取行数?

java - lambda 实际上是一个匿名类吗?

java - Jersey 框架中的映射方法

java - 从java中的枚举列表中删除一个元素

java - 解析未知 TemporalAccessor 的字符串

Java 8 -- 如何使用 xsd :duration 计算从现在开始的(毫秒)秒