quickfixj icon indicating copy to clipboard operation
quickfixj copied to clipboard

Improve `UtcTimeStampField` instantiation time

Open raipc opened this issue 3 years ago • 2 comments

LocalDateTime.now(ZoneOffset) is slow because a new ConcurrentHashMap object is allocated each time on ZoneRules instance creation, and SystemClock is instantiated in Java 8.

Benchmark results for Java 8

Benchmark                                                                                 Mode      Cnt        Score    Error   Units
LocalDateTimeInitBenchmark.withCachedClockWithOffset                                    sample  1291695      423.817 ± 66.584   ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:withCachedClockWithOffset·p0.00    sample               145.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:withCachedClockWithOffset·p0.50    sample               148.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:withCachedClockWithOffset·p0.90    sample               152.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:withCachedClockWithOffset·p0.95    sample               154.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:withCachedClockWithOffset·p0.99    sample               248.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:withCachedClockWithOffset·p0.999   sample             15421.184            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:withCachedClockWithOffset·p0.9999  sample            754514.330            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:withCachedClockWithOffset·p1.00    sample           9011200.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:·gc.alloc.rate                     sample        5      956.213 ± 48.297  MB/sec
LocalDateTimeInitBenchmark.withCachedClockWithOffset:·gc.alloc.rate.norm                sample        5      160.007 ±  0.001    B/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:·gc.churn.Eden_Space               sample        5      961.186 ± 48.232  MB/sec
LocalDateTimeInitBenchmark.withCachedClockWithOffset:·gc.churn.Eden_Space.norm          sample        5      160.839 ±  0.136    B/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:·gc.churn.Survivor_Space           sample        5        0.023 ±  0.024  MB/sec
LocalDateTimeInitBenchmark.withCachedClockWithOffset:·gc.churn.Survivor_Space.norm      sample        5        0.004 ±  0.004    B/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:·gc.count                          sample        5    11719.000           counts
LocalDateTimeInitBenchmark.withCachedClockWithOffset:·gc.time                           sample        5     3503.000               ms
LocalDateTimeInitBenchmark.withCachedClockWithZoneId                                    sample  1455543      273.973 ± 34.260   ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:withCachedClockWithZoneId·p0.00    sample               145.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:withCachedClockWithZoneId·p0.50    sample               148.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:withCachedClockWithZoneId·p0.90    sample               149.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:withCachedClockWithZoneId·p0.95    sample               153.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:withCachedClockWithZoneId·p0.99    sample               213.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:withCachedClockWithZoneId·p0.999   sample              9744.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:withCachedClockWithZoneId·p0.9999  sample            433268.736            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:withCachedClockWithZoneId·p1.00    sample           5955584.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:·gc.alloc.rate                     sample        5      485.588 ± 12.884  MB/sec
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:·gc.alloc.rate.norm                sample        5       72.006 ±  0.002    B/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:·gc.churn.Eden_Space               sample        5      488.058 ± 13.101  MB/sec
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:·gc.churn.Eden_Space.norm          sample        5       72.372 ±  0.116    B/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:·gc.churn.Survivor_Space           sample        5        0.018 ±  0.024  MB/sec
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:·gc.churn.Survivor_Space.norm      sample        5        0.003 ±  0.004    B/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:·gc.count                          sample        5     5948.000           counts
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:·gc.time                           sample        5     1980.000               ms
LocalDateTimeInitBenchmark.withInstant                                                  sample  1478108      268.301 ± 40.532   ns/op
LocalDateTimeInitBenchmark.withInstant:withInstant·p0.00                                sample               141.000            ns/op
LocalDateTimeInitBenchmark.withInstant:withInstant·p0.50                                sample               144.000            ns/op
LocalDateTimeInitBenchmark.withInstant:withInstant·p0.90                                sample               144.000            ns/op
LocalDateTimeInitBenchmark.withInstant:withInstant·p0.95                                sample               147.000            ns/op
LocalDateTimeInitBenchmark.withInstant:withInstant·p0.99                                sample               210.000            ns/op
LocalDateTimeInitBenchmark.withInstant:withInstant·p0.999                               sample              9824.000            ns/op
LocalDateTimeInitBenchmark.withInstant:withInstant·p0.9999                              sample            212194.406            ns/op
LocalDateTimeInitBenchmark.withInstant:withInstant·p1.00                                sample           8175616.000            ns/op
LocalDateTimeInitBenchmark.withInstant:·gc.alloc.rate                                   sample        5      493.089 ± 11.416  MB/sec
LocalDateTimeInitBenchmark.withInstant:·gc.alloc.rate.norm                              sample        5       72.006 ±  0.001    B/op
LocalDateTimeInitBenchmark.withInstant:·gc.churn.Eden_Space                             sample        5      495.585 ± 11.301  MB/sec
LocalDateTimeInitBenchmark.withInstant:·gc.churn.Eden_Space.norm                        sample        5       72.370 ±  0.116    B/op
LocalDateTimeInitBenchmark.withInstant:·gc.churn.Survivor_Space                         sample        5        0.019 ±  0.027  MB/sec
LocalDateTimeInitBenchmark.withInstant:·gc.churn.Survivor_Space.norm                    sample        5        0.003 ±  0.004    B/op
LocalDateTimeInitBenchmark.withInstant:·gc.count                                        sample        5     6039.000           counts
LocalDateTimeInitBenchmark.withInstant:·gc.time                                         sample        5     2006.000               ms
LocalDateTimeInitBenchmark.withZoneOffset                                               sample  1297158      360.455 ± 46.250   ns/op
LocalDateTimeInitBenchmark.withZoneOffset:withZoneOffset·p0.00                          sample               143.000            ns/op
LocalDateTimeInitBenchmark.withZoneOffset:withZoneOffset·p0.50                          sample               147.000            ns/op
LocalDateTimeInitBenchmark.withZoneOffset:withZoneOffset·p0.90                          sample               149.000            ns/op
LocalDateTimeInitBenchmark.withZoneOffset:withZoneOffset·p0.95                          sample               152.000            ns/op
LocalDateTimeInitBenchmark.withZoneOffset:withZoneOffset·p0.99                          sample               245.000            ns/op
LocalDateTimeInitBenchmark.withZoneOffset:withZoneOffset·p0.999                         sample             12314.912            ns/op
LocalDateTimeInitBenchmark.withZoneOffset:withZoneOffset·p0.9999                        sample            727179.674            ns/op
LocalDateTimeInitBenchmark.withZoneOffset:withZoneOffset·p1.00                          sample           8454144.000            ns/op
LocalDateTimeInitBenchmark.withZoneOffset:·gc.alloc.rate                                sample        5      960.880 ± 49.084  MB/sec
LocalDateTimeInitBenchmark.withZoneOffset:·gc.alloc.rate.norm                           sample        5      160.006 ±  0.002    B/op
LocalDateTimeInitBenchmark.withZoneOffset:·gc.churn.Eden_Space                          sample        5      965.832 ± 49.265  MB/sec
LocalDateTimeInitBenchmark.withZoneOffset:·gc.churn.Eden_Space.norm                     sample        5      160.831 ±  0.097    B/op
LocalDateTimeInitBenchmark.withZoneOffset:·gc.churn.Survivor_Space                      sample        5        0.022 ±  0.025  MB/sec
LocalDateTimeInitBenchmark.withZoneOffset:·gc.churn.Survivor_Space.norm                 sample        5        0.004 ±  0.004    B/op
LocalDateTimeInitBenchmark.withZoneOffset:·gc.count                                     sample        5    11770.000           counts
LocalDateTimeInitBenchmark.withZoneOffset:·gc.time                                      sample        5     3665.000               ms

For Java 11.0.1:

Benchmark                                                                                 Mode      Cnt         Score    Error   Units
LocalDateTimeInitBenchmark.withCachedClockWithOffset                                    sample  1470919       288.459 ± 45.150   ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:withCachedClockWithOffset·p0.00    sample                150.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:withCachedClockWithOffset·p0.50    sample                157.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:withCachedClockWithOffset·p0.90    sample                161.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:withCachedClockWithOffset·p0.95    sample                162.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:withCachedClockWithOffset·p0.99    sample                173.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:withCachedClockWithOffset·p0.999   sample              10273.280            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:withCachedClockWithOffset·p0.9999  sample             266840.064            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:withCachedClockWithOffset·p1.00    sample           11468800.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:·gc.alloc.rate                     sample        5       492.719 ± 13.240  MB/sec
LocalDateTimeInitBenchmark.withCachedClockWithOffset:·gc.alloc.rate.norm                sample        5        72.367 ±  0.001    B/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:·gc.churn.Eden_Space               sample        5       496.778 ± 13.892  MB/sec
LocalDateTimeInitBenchmark.withCachedClockWithOffset:·gc.churn.Eden_Space.norm          sample        5        72.963 ±  0.130    B/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:·gc.churn.Survivor_Space           sample        5         0.019 ±  0.026  MB/sec
LocalDateTimeInitBenchmark.withCachedClockWithOffset:·gc.churn.Survivor_Space.norm      sample        5         0.003 ±  0.004    B/op
LocalDateTimeInitBenchmark.withCachedClockWithOffset:·gc.count                          sample        5      6056.000           counts
LocalDateTimeInitBenchmark.withCachedClockWithOffset:·gc.time                           sample        5       996.000               ms
LocalDateTimeInitBenchmark.withCachedClockWithZoneId                                    sample  1407962       266.332 ± 26.969   ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:withCachedClockWithZoneId·p0.00    sample                154.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:withCachedClockWithZoneId·p0.50    sample                164.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:withCachedClockWithZoneId·p0.90    sample                166.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:withCachedClockWithZoneId·p0.95    sample                168.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:withCachedClockWithZoneId·p0.99    sample                192.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:withCachedClockWithZoneId·p0.999   sample              10224.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:withCachedClockWithZoneId·p0.9999  sample             237108.147            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:withCachedClockWithZoneId·p1.00    sample            5824512.000            ns/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:·gc.alloc.rate                     sample        5       471.574 ± 26.946  MB/sec
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:·gc.alloc.rate.norm                sample        5        72.367 ±  0.001    B/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:·gc.churn.Eden_Space               sample        5       475.537 ± 27.027  MB/sec
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:·gc.churn.Eden_Space.norm          sample        5        72.976 ±  0.070    B/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:·gc.churn.Survivor_Space           sample        5         0.019 ±  0.026  MB/sec
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:·gc.churn.Survivor_Space.norm      sample        5         0.003 ±  0.004    B/op
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:·gc.count                          sample        5      5797.000           counts
LocalDateTimeInitBenchmark.withCachedClockWithZoneId:·gc.time                           sample        5       905.000               ms
LocalDateTimeInitBenchmark.withInstant                                                  sample  1507183       248.806 ± 32.901   ns/op
LocalDateTimeInitBenchmark.withInstant:withInstant·p0.00                                sample                141.000            ns/op
LocalDateTimeInitBenchmark.withInstant:withInstant·p0.50                                sample                150.000            ns/op
LocalDateTimeInitBenchmark.withInstant:withInstant·p0.90                                sample                154.000            ns/op
LocalDateTimeInitBenchmark.withInstant:withInstant·p0.95                                sample                156.000            ns/op
LocalDateTimeInitBenchmark.withInstant:withInstant·p0.99                                sample                186.000            ns/op
LocalDateTimeInitBenchmark.withInstant:withInstant·p0.999                               sample               9949.056            ns/op
LocalDateTimeInitBenchmark.withInstant:withInstant·p0.9999                              sample             153520.538            ns/op
LocalDateTimeInitBenchmark.withInstant:withInstant·p1.00                                sample            7471104.000            ns/op
LocalDateTimeInitBenchmark.withInstant:·gc.alloc.rate                                   sample        5       505.027 ± 25.777  MB/sec
LocalDateTimeInitBenchmark.withInstant:·gc.alloc.rate.norm                              sample        5        72.367 ±  0.001    B/op
LocalDateTimeInitBenchmark.withInstant:·gc.churn.Eden_Space                             sample        5       509.259 ± 25.798  MB/sec
LocalDateTimeInitBenchmark.withInstant:·gc.churn.Eden_Space.norm                        sample        5        72.973 ±  0.047    B/op
LocalDateTimeInitBenchmark.withInstant:·gc.churn.Survivor_Space                         sample        5         0.019 ±  0.026  MB/sec
LocalDateTimeInitBenchmark.withInstant:·gc.churn.Survivor_Space.norm                    sample        5         0.003 ±  0.004    B/op
LocalDateTimeInitBenchmark.withInstant:·gc.count                                        sample        5      6208.000           counts
LocalDateTimeInitBenchmark.withInstant:·gc.time                                         sample        5       989.000               ms
LocalDateTimeInitBenchmark.withZoneOffset                                               sample  1460212       261.188 ± 28.140   ns/op
LocalDateTimeInitBenchmark.withZoneOffset:withZoneOffset·p0.00                          sample                150.000            ns/op
LocalDateTimeInitBenchmark.withZoneOffset:withZoneOffset·p0.50                          sample                157.000            ns/op
LocalDateTimeInitBenchmark.withZoneOffset:withZoneOffset·p0.90                          sample                160.000            ns/op
LocalDateTimeInitBenchmark.withZoneOffset:withZoneOffset·p0.95                          sample                162.000            ns/op
LocalDateTimeInitBenchmark.withZoneOffset:withZoneOffset·p0.99                          sample                198.000            ns/op
LocalDateTimeInitBenchmark.withZoneOffset:withZoneOffset·p0.999                         sample              10112.000            ns/op
LocalDateTimeInitBenchmark.withZoneOffset:withZoneOffset·p0.9999                        sample             231396.736            ns/op
LocalDateTimeInitBenchmark.withZoneOffset:withZoneOffset·p1.00                          sample            7806976.000            ns/op
LocalDateTimeInitBenchmark.withZoneOffset:·gc.alloc.rate                                sample        5       489.174 ± 10.272  MB/sec
LocalDateTimeInitBenchmark.withZoneOffset:·gc.alloc.rate.norm                           sample        5        72.367 ±  0.001    B/op
LocalDateTimeInitBenchmark.withZoneOffset:·gc.churn.Eden_Space                          sample        5       493.184 ± 10.475  MB/sec
LocalDateTimeInitBenchmark.withZoneOffset:·gc.churn.Eden_Space.norm                     sample        5        72.960 ±  0.031    B/op
LocalDateTimeInitBenchmark.withZoneOffset:·gc.churn.Survivor_Space                      sample        5         0.019 ±  0.026  MB/sec
LocalDateTimeInitBenchmark.withZoneOffset:·gc.churn.Survivor_Space.norm                 sample        5         0.003 ±  0.004    B/op
LocalDateTimeInitBenchmark.withZoneOffset:·gc.count                                     sample        5      6012.000           counts
LocalDateTimeInitBenchmark.withZoneOffset:·gc.time                                      sample        5       979.000               ms

raipc avatar Dec 23 '21 22:12 raipc

Thanks @raipc , looking good. Could you please add the code for the benchmark as a comment or attach it? Thank you very much.

chrjohn avatar Jan 04 '22 21:01 chrjohn

Thanks @raipc , looking good. Could you please add the code for the benchmark as a comment or attach it? Thank you very much.

@chrjohn , sure

import org.openjdk.jmh.annotations.Benchmark;

import java.time.*;

public class LocalDateTimeInitBenchmark {
    private static final Clock systemClockWithOffset = Clock.system(ZoneOffset.UTC);
    private static final Clock systemClockWithZoneId = Clock.system(ZoneId.of("UTC"));

    @Benchmark
    public LocalDateTime withZoneOffset() {
        return LocalDateTime.now(ZoneOffset.UTC);
    }

    @Benchmark
    public LocalDateTime withCachedClockWithOffset() {
        return LocalDateTime.now(systemClockWithOffset);
    }

    @Benchmark
    public LocalDateTime withCachedClockWithZoneId() {
        return LocalDateTime.now(systemClockWithZoneId);
    }

    @Benchmark
    public LocalDateTime withInstant() {
        final Instant instant = systemClockWithZoneId.instant();
        return LocalDateTime.ofEpochSecond(instant.getEpochSecond(), instant.getNano(), ZoneOffset.UTC);
    }
}

raipc avatar Jan 06 '22 06:01 raipc