mirror of
https://github.com/golang/go
synced 2024-11-23 00:10:07 -07:00
time: optimize Format for RFC3339 and RFC3339Nano
Optimise Format for the most frequently used RFC3339 and RFC3339Nano layouts by avoiding parsing of layout. > benchstat oldBench.txt newBench.txt name old time/op new time/op delta FormatRFC3339-8 302ns ± 1% 203ns ± 0% -32.89% (p=0.016 n=5+4) FormatRFC3339Nano-8 337ns ± 1% 219ns ± 1% -34.91% (p=0.008 n=5+5) name old alloc/op new alloc/op delta FormatRFC3339-8 32.0B ± 0% 32.0B ± 0% ~ (all equal) FormatRFC3339Nano-8 32.0B ± 0% 32.0B ± 0% ~ (all equal) name old allocs/op new allocs/op delta FormatRFC3339-8 1.00 ± 0% 1.00 ± 0% ~ (all equal) FormatRFC3339Nano-8 1.00 ± 0% 1.00 ± 0% ~ (all equal) Fixes #54093 Change-Id: Ifc84fce6078e24514ecbcd234875bca4aaab5e0e Reviewed-on: https://go-review.googlesource.com/c/go/+/421877 Run-TryBot: Ian Lance Taylor <iant@google.com> Auto-Submit: Joseph Tsai <joetsai@digital-static.net> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Ian Lance Taylor <iant@google.com> Reviewed-by: Than McIntosh <thanm@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Joseph Tsai <joetsai@digital-static.net> Run-TryBot: Joseph Tsai <joetsai@digital-static.net>
This commit is contained in:
parent
8298c545f3
commit
133c0e9011
@ -626,6 +626,15 @@ func (t Time) AppendFormat(b []byte, layout string) []byte {
|
|||||||
min int
|
min int
|
||||||
sec int
|
sec int
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Handle most frequent layouts separately.
|
||||||
|
switch layout {
|
||||||
|
case RFC3339:
|
||||||
|
return t.appendFormatRFC3339(b, abs, offset, false)
|
||||||
|
case RFC3339Nano:
|
||||||
|
return t.appendFormatRFC3339(b, abs, offset, true)
|
||||||
|
}
|
||||||
|
|
||||||
// Each iteration generates one std value.
|
// Each iteration generates one std value.
|
||||||
for layout != "" {
|
for layout != "" {
|
||||||
prefix, std, suffix := nextStdChunk(layout)
|
prefix, std, suffix := nextStdChunk(layout)
|
||||||
@ -781,6 +790,48 @@ func (t Time) AppendFormat(b []byte, layout string) []byte {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t Time) appendFormatRFC3339(b []byte, abs uint64, offset int, nanos bool) []byte {
|
||||||
|
// Format date.
|
||||||
|
year, month, day, _ := absDate(abs, true)
|
||||||
|
b = appendInt(b, year, 4)
|
||||||
|
b = append(b, '-')
|
||||||
|
b = appendInt(b, int(month), 2)
|
||||||
|
b = append(b, '-')
|
||||||
|
b = appendInt(b, day, 2)
|
||||||
|
|
||||||
|
b = append(b, 'T')
|
||||||
|
|
||||||
|
// Format time.
|
||||||
|
hour, min, sec := absClock(abs)
|
||||||
|
b = appendInt(b, hour, 2)
|
||||||
|
b = append(b, ':')
|
||||||
|
b = appendInt(b, min, 2)
|
||||||
|
b = append(b, ':')
|
||||||
|
b = appendInt(b, sec, 2)
|
||||||
|
|
||||||
|
if nanos {
|
||||||
|
std := stdFracSecond(stdFracSecond9, 9, '.')
|
||||||
|
b = formatNano(b, uint(t.Nanosecond()), std)
|
||||||
|
}
|
||||||
|
|
||||||
|
if offset == 0 {
|
||||||
|
return append(b, 'Z')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format zone.
|
||||||
|
zone := offset / 60 // convert to minutes
|
||||||
|
if zone < 0 {
|
||||||
|
b = append(b, '-')
|
||||||
|
zone = -zone
|
||||||
|
} else {
|
||||||
|
b = append(b, '+')
|
||||||
|
}
|
||||||
|
b = appendInt(b, zone/60, 2)
|
||||||
|
b = append(b, ':')
|
||||||
|
b = appendInt(b, zone%60, 2)
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
var errBad = errors.New("bad value for field") // placeholder not passed to user
|
var errBad = errors.New("bad value for field") // placeholder not passed to user
|
||||||
|
|
||||||
// ParseError describes a problem parsing a time string.
|
// ParseError describes a problem parsing a time string.
|
||||||
|
@ -1402,6 +1402,20 @@ func BenchmarkFormat(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkFormatRFC3339(b *testing.B) {
|
||||||
|
t := Unix(1265346057, 0)
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
t.Format("2006-01-02T15:04:05Z07:00")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkFormatRFC3339Nano(b *testing.B) {
|
||||||
|
t := Unix(1265346057, 0)
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
t.Format("2006-01-02T15:04:05.999999999Z07:00")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkFormatNow(b *testing.B) {
|
func BenchmarkFormatNow(b *testing.B) {
|
||||||
// Like BenchmarkFormat, but easier, because the time zone
|
// Like BenchmarkFormat, but easier, because the time zone
|
||||||
// lookup cache is optimized for the present.
|
// lookup cache is optimized for the present.
|
||||||
|
Loading…
Reference in New Issue
Block a user