Josh Bleecher Snyder
aa9d7f4665
tstime: add Parse3339B, for byte slices
...
Use go4.org/mem for memory safety.
A slight performance hit, but a huge performance win
for clients who start with a []byte.
The perf hit is due largely to the MapHash call, which adds ~25ns.
That is necessary to keep the fast path allocation-free.
name old time/op new time/op delta
GoParse3339/Z-8 281ns ± 1% 283ns ± 2% ~ (p=0.366 n=9+9)
GoParse3339/TZ-8 509ns ± 0% 510ns ± 1% ~ (p=0.059 n=9+9)
GoParse3339InLocation-8 330ns ± 1% 330ns ± 0% ~ (p=0.802 n=10+6)
Parse3339/Z-8 69.3ns ± 1% 74.4ns ± 1% +7.45% (p=0.000 n=9+10)
Parse3339/TZ-8 110ns ± 1% 140ns ± 3% +27.42% (p=0.000 n=9+10)
ParseInt-8 8.20ns ± 1% 8.17ns ± 1% ~ (p=0.452 n=9+9)
name old alloc/op new alloc/op delta
GoParse3339/Z-8 0.00B 0.00B ~ (all equal)
GoParse3339/TZ-8 160B ± 0% 160B ± 0% ~ (all equal)
GoParse3339InLocation-8 0.00B 0.00B ~ (all equal)
Parse3339/Z-8 0.00B 0.00B ~ (all equal)
Parse3339/TZ-8 0.00B 0.00B ~ (all equal)
name old allocs/op new allocs/op delta
GoParse3339/Z-8 0.00 0.00 ~ (all equal)
GoParse3339/TZ-8 3.00 ± 0% 3.00 ± 0% ~ (all equal)
GoParse3339InLocation-8 0.00 0.00 ~ (all equal)
Parse3339/Z-8 0.00 0.00 ~ (all equal)
Parse3339/TZ-8 0.00 0.00 ~ (all equal)
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2020-11-19 14:47:11 -08:00
David Anderson
b925e18f70
tstime: hand-implement parseInt for specific needs of rfc3339 parsing.
...
Makes parsing 4.6x faster.
name old time/op new time/op delta
ParseInt-12 32.1ns ± 1% 6.9ns ± 2% -78.55% (p=0.000 n=10+9)
Signed-off-by: David Anderson <danderson@tailscale.com>
2020-04-14 12:36:55 -07:00
Brad Fitzpatrick
febdac0499
tstime: write Parse3339 parse that doesn't use time.Parse
...
It doesn't allocate and it's half the time of time.Parse (which
allocates), and 2/3rds the time of time.ParseInLocation (which
doesn't).
Go with a UTC time:
BenchmarkGoParse3339/Z-8 2200995 534 ns/op 0 B/op 0 allocs/op
BenchmarkGoParse3339/Z-8 2254816 554 ns/op 0 B/op 0 allocs/op
BenchmarkGoParse3339/Z-8 2159504 522 ns/op 0 B/op 0 allocs/op
Go allocates with a "-08:00" suffix instead of ending in "Z":
BenchmarkGoParse3339/TZ-8 1276491 884 ns/op 144 B/op 3 allocs/op
BenchmarkGoParse3339/TZ-8 1355858 942 ns/op 144 B/op 3 allocs/op
BenchmarkGoParse3339/TZ-8 1385484 911 ns/op 144 B/op 3 allocs/op
Go doesn't allocate if you use time.ParseInLocation, but then you need
to parse the string to find the location anyway, so might as well go
all the way (below).
BenchmarkGoParse3339InLocation-8 1912254 597 ns/op 0 B/op 0 allocs/op
BenchmarkGoParse3339InLocation-8 1980043 612 ns/op 0 B/op 0 allocs/op
BenchmarkGoParse3339InLocation-8 1891366 612 ns/op 0 B/op 0 allocs/op
Parsing RFC3339 ourselves, UTC:
BenchmarkParse3339/Z-8 3889220 307 ns/op 0 B/op 0 allocs/op
BenchmarkParse3339/Z-8 3718500 309 ns/op 0 B/op 0 allocs/op
BenchmarkParse3339/Z-8 3621231 303 ns/op 0 B/op 0 allocs/op
Parsing RFC3339 ourselves, with timezone (w/ *time.Location fetched
from sync.Map)
BenchmarkParse3339/TZ-8 3019612 418 ns/op 0 B/op 0 allocs/op
BenchmarkParse3339/TZ-8 2921618 401 ns/op 0 B/op 0 allocs/op
BenchmarkParse3339/TZ-8 3031671 408 ns/op 0 B/op 0 allocs/op
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-04-06 08:19:17 -07:00
Brad Fitzpatrick
d503dee6f1
tstime: add new package for time utilities, starting with Parse3339
...
Go's time.Parse always allocates a FixedZone for time strings not in
UTC (ending in "Z"). This avoids that allocation, at the cost of
adding a cache.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-04-05 20:05:49 -07:00