java.time.ZoneId.systemDefalut() overhead
Daniel Fuchs
daniel.fuchs at oracle.com
Mon Feb 23 09:50:28 UTC 2015
Hi Peter,
On 22/02/15 21:21, Peter Levart wrote:
> Hi,
>
> I noticed internal JDK class java.util.zip.ZipUtils uses deprecated
> java.util.Date API for implementing two methods for converting DOS to
> Java time and back. I thought I'd try translating them to use new
> java.time API. Translation was straightforward, but I noticed that new
> implementations are not on par with speed to old java.util.Date
> versions. Here's a JMH benchmark implementing those two conversion
> methods with java.util.Date and java.time.ZonedDateTime APIs:
>
> http://cr.openjdk.java.net/~plevart/jdk9-dev/ZoneId.systemDefault/ZipUtilsTest.java
>
>
> The results show the following:
>
> Benchmark Mode Samples Score Score
> error Units
> j.t.ZipUtilsTest.dosToJavaTime_Date avgt 5 101.890 17.570
> ns/op
> j.t.ZipUtilsTest.dosToJavaTime_ZDT avgt 5 137.587 13.533
> ns/op
> j.t.ZipUtilsTest.javaToDosTime_Date avgt 5 67.114 10.382 ns/op
> j.t.ZipUtilsTest.javaToDosTime_ZDT avgt 5 143.739 15.243
> ns/op
>
>
> Quick sampling with jvisualvm shows that a substantial time is spent
> repeatedly obtaining ZoneId.systemDefault() instance. I checked the
> implementation and came up with the following optimization:
>
> http://cr.openjdk.java.net/~plevart/jdk9-dev/ZoneId.systemDefault/webrev.01/
It will be good to hear what Stephen will have to say about this.
Also I see that Claes is suggesting using LocalDateTime.
If there's no undesirable side effect then caching zoneId
inside TimeZone looks reasonable to me - however I'm not an expert
of the field, and I got to learn that time/date can be more complex
than what I first thought ;-)
The use of SharedSecrets seems rather ugly though - and its only
purpose seems to avoid a clone(). I have to wonder whether there
is a significant performance gain in this. I mean - if you simply
cached zoneId in TimeZone and called TimeZone.getDefault() directly,
how worse would that be?
Finally, I also wonder whether a better idea would be to add
a variant of dosToJavaTime/javaToDosTime that would take an
additional zoneId as parameter.
You probably don't want to support changing the time zone in
the middle of a Zip. Do you?
best regards,
-- daniel
>
>
> TimeZone is a mutable object and has to be defensively cloned when
> TimeZone.getDefault() is invoked. So there's no point in caching a
> ZoneId instance inside TimeZone instance if we cache it on a clone that
> is thrown away each time ZoneId.systemDefault() is invoked. I use
> SharedSecrets to access the uncloned TimeZone.defaultTimeZone instance
> where caching of ZoneId pays of.
>
> I think that it was never meant to change TimeZone's ID
> (TimeZone.setID()) after such instance was put into operation (for
> example installed as default time zone with TimeZone.setDefault()). Such
> use is unintended and buggy. So I also changed the implementation of
> TimeZone.setDefault() to save a defensive copy of TimeZone object as
> default time zone instead of a reference to it.
>
> With this patch, the DOS/Java time conversion benchmark shows an
> improvement:
>
> Benchmark Mode Samples Score Score
> error Units
> j.t.ZipUtilsTest.dosToJavaTime_Date avgt 5 97.986 18.379 ns/op
> j.t.ZipUtilsTest.dosToJavaTime_ZDT avgt 5 85.010 10.863 ns/op
> j.t.ZipUtilsTest.javaToDosTime_Date avgt 5 71.073 25.408 ns/op
> j.t.ZipUtilsTest.javaToDosTime_ZDT avgt 5 95.298 17.620 ns/op
>
>
> Is this patch correct or did I miss something from the internals of
> java.time API that does not permit such caching?
>
>
> Regards, Peter
>
More information about the core-libs-dev
mailing list