达令说
据我所知,答案是否定的,没有其他库可以将2018-01-02T12:34:56+00:00"(ISO 8601 格式)等字符串解析为OffsetDateTime对象。如果存在的话,我会期望听到或读到它。我对下一点如履薄冰,但我也认为标准库(AKA java.time)足够高效,并且可能与您期望的一样快。编辑:我很好奇并编写了自己的 parse 方法,看看我是否能够胜过 one-arg OffsetDateTime.parse。我曾是。我自己的方法(以下来源)没有内置方法的灵活性,它只接受标准格式的大量变体中的一个,这可能是它在性能方面的强项。解析你的字符串一百万次需要:1.034 秒使用OffsetDateTime.parse0.117秒用我自己的方法这不是推荐!我可能永远不会使用我自己的方法。出于绝大多数目的,维护负担是不值得的。如果有一天出现了 ISO 8601 的不同变体,您将遇到昂贵的支持问题和错误修复。我的方法很简单:private static final OffsetDateTime parse(String s) { char offsetSign; if (s.length() != 25 || s.charAt(4) != '-' || s.charAt(7) != '-' || s.charAt(10) != 'T' || s.charAt(13) != ':' || s.charAt(16) != ':' || ((offsetSign = s.charAt(19)) != '+' && offsetSign != '-') || s.charAt(22) != ':') { throw new IllegalArgumentException(); } int offsetHours = Integer.parseInt(s.substring(20, 22)); int offsetMinutes = Integer.parseInt(s.substring(23, 25)); if (offsetSign == '-') { offsetHours = -offsetHours; offsetMinutes = -offsetMinutes; } return OffsetDateTime.of(Integer.parseInt(s.substring(0, 4)), Integer.parseInt(s.substring(5, 7)), Integer.parseInt(s.substring(8, 10)), Integer.parseInt(s.substring(11, 13)), Integer.parseInt(s.substring(14, 16)), Integer.parseInt(s.substring(17, 19)), 0, ZoneOffset.ofHoursMinutes(offsetHours, offsetMinutes));}我知道代码中的错误。我认为不值得彻底测试并修复此答案的错误,因为它不太可能对性能产生太大影响。
呼唤远方
每次解析不到一毫秒,您不必担心优化解析OffsetDateTime。当然,你必须有更大的鱼来炸。细节让我们尝试一个小基准测试。警告:微基准是出了名的不可靠。但希望这能让我们接近现实的理解。警告:我匆匆写下这段代码和这篇文章。请仔细检查我的工作。在我试图避免 JVM 优化运行时的微弱尝试中,我使用了 31 个不同的值,一个用于 1 月份的每一天。我将这些重复一千次以获得 31,000 个列表。然后我洗牌了。尽管如此,我的结果表明在运行时进行了大量优化。每次解析的纳秒数因循环数而变化很大。100_000 次循环 = 每次解析 1,573 纳秒(1 微秒)10_000 = 4,2431_000 = 10,177100 = 31,1251 = 每次解析 693,687 纳秒。(693 微秒,超过半毫秒)。我使用了 Azul Systems 的 Java 11 JVM Zulu产品,这是一个基于 OpenJDK 版本 11.0.2 的实现。在 MacBook Pro(Retina,15 英寸,2013 年末)、2.3 GHz Intel Core i7、16 GB 1600 MHz DDR3 上运行。结果总结:少数几个最坏的情况是每次解析不到一毫秒。最好的情况是每个只有一微秒。我的结论:不要担心解析您的OffsetDateTime输入字符串。您可能会陷入过早优化的陷阱。代码。System.out.println( "INFO - Starting the OffsetDateTime parsing benchmark." );List < String > inputsShort = new ArrayList <>( 31 );inputsShort.add( "2018-01-01T12:34:56+00:00" );inputsShort.add( "2018-01-02T12:34:56+00:00" );inputsShort.add( "2018-01-03T12:34:56+00:00" );inputsShort.add( "2018-01-04T12:34:56+00:00" );inputsShort.add( "2018-01-05T12:34:56+00:00" );inputsShort.add( "2018-01-06T12:34:56+00:00" );inputsShort.add( "2018-01-07T12:34:56+00:00" );inputsShort.add( "2018-01-08T12:34:56+00:00" );inputsShort.add( "2018-01-09T12:34:56+00:00" );inputsShort.add( "2018-01-10T12:34:56+00:00" );inputsShort.add( "2018-01-11T12:34:56+00:00" );inputsShort.add( "2018-01-12T12:34:56+00:00" );inputsShort.add( "2018-01-13T12:34:56+00:00" );inputsShort.add( "2018-01-14T12:34:56+00:00" );inputsShort.add( "2018-01-15T12:34:56+00:00" );inputsShort.add( "2018-01-16T12:34:56+00:00" );inputsShort.add( "2018-01-17T12:34:56+00:00" );inputsShort.add( "2018-01-18T12:34:56+00:00" );inputsShort.add( "2018-01-19T12:34:56+00:00" );inputsShort.add( "2018-01-20T12:34:56+00:00" );inputsShort.add( "2018-01-21T12:34:56+00:00" );inputsShort.add( "2018-01-22T12:34:56+00:00" );inputsShort.add( "2018-01-23T12:34:56+00:00" );inputsShort.add( "2018-01-24T12:34:56+00:00" );inputsShort.add( "2018-01-25T12:34:56+00:00" );inputsShort.add( "2018-01-26T12:34:56+00:00" );inputsShort.add( "2018-01-27T12:34:56+00:00" );inputsShort.add( "2018-01-28T12:34:56+00:00" );inputsShort.add( "2018-01-29T12:34:56+00:00" );inputsShort.add( "2018-01-30T12:34:56+00:00" );inputsShort.add( "2018-01-31T12:34:56+00:00" );int loops = 100; // 100_000=1,573 nanos each parse. 10_000=4,243. 1_000=10,177. 100=31,125. 1=693,687 nanos each parse.List < String > inputs = new ArrayList <>( inputsShort.size() * loops );for ( int i = 1 ; i <= loops ; i++ ) { inputs.addAll( inputsShort );}Collections.shuffle( inputs );//System.out.println( inputs );long start = System.nanoTime();for ( String input : inputs ) { OffsetDateTime odt = OffsetDateTime.parse( input );}long stop = System.nanoTime();long nanosPerParse = ( ( stop - start ) / inputs.size() );System.out.println( "INFO: nanosPerParse: " + nanosPerParse + " for a count of: " + inputs.size() + "." );