]> Cypherpunks repositories - gostls13.git/commit
time: optimize Parse for []byte arguments
authorJoe Tsai <joetsai@digital-static.net>
Thu, 8 Sep 2022 21:57:44 +0000 (14:57 -0700)
committerJoseph Tsai <joetsai@digital-static.net>
Tue, 20 Sep 2022 16:21:31 +0000 (16:21 +0000)
commitbcd44b61d3154b22ffce10302ea9c34ba639a98e
treeb9ab0a0cfb628b5e219b0ea3351a074f6b60e6f1
parent0bfa9f0435e03176b04ad202320be441d03ee25f
time: optimize Parse for []byte arguments

When one has a []byte on hand, but desires to call the Parse function,
the conversion from []byte to string would allocate.
This occurs frequently through UnmarshalText and UnmarshalJSON.

This changes it such that the input string never escapes from
any of the Parse functions. Together with the compiler optimization
where the compiler stack allocates any string smaller than 32B
this makes most valid inputs for Parse(layout, string(input))
not require an allocation for the input string.

This optimization works well for most RFC3339 timestamps.
All timestamps with second resolution
(e.g., 2000-01-01T00:00:00Z or 2000-01-01T00:00:00+23:59)
or timestamps with nanosecond resolution in UTC
(e.g., 2000-01-01T00:00:00.123456789Z)
are less than 32B and benefit from this optimization.
Unfortunately, nanosecond timestamps with non-UTC timezones
(e.g., 2000-01-01T00:00:00.123456789+23:59)
do not benefit since they are 35B long.

Previously, this was not possible since the input leaked
to the error and calls to FixedZone with the zone name,
which causes the prover to give up and heap copy the []byte.
We fix this by copying the input string in both cases.
The advantage of this change is that you can now call Parse
with a []byte without allocating (most of the times).
The detriment is that the timezone and error path has an extra allocation.
Handling of timezones were already expensive (3 allocations and 160B allocated),
so the additional cost of another string allocation is relatively minor.
We should optimize for the common case, rather than the exceptional case.

Performance:

    name                  old time/op  new time/op  delta
    ParseRFC3339UTCBytes  54.4ns ± 1%  40.3ns ± 1%  -25.91%  (p=0.000 n=9+10)

Now that parsing of RFC3339 has been heavily optimized in CL 425197,
the performance gains by this optimization becomes relatively more notable.

Related to CL 345488.

Change-Id: I2a8a9cd6354b3bd46c2f57818ed2646a2e485f36
Reviewed-on: https://go-review.googlesource.com/c/go/+/429862
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Joseph Tsai <joetsai@digital-static.net>
TryBot-Result: Gopher Robot <gobot@golang.org>
src/time/format.go
src/time/time_test.go