]> Cypherpunks repositories - gostls13.git/commitdiff
time: optimize GoString
authorAmarjeet Anand <amarjeetanandsingh@gmail.com>
Sat, 13 Aug 2022 16:30:33 +0000 (22:00 +0530)
committerGopher Robot <gobot@golang.org>
Wed, 17 Aug 2022 04:10:17 +0000 (04:10 +0000)
Optimize Time.GoString by avoiding multiple calls to absDate.

name        old time/op    new time/op    delta
GoString-8     313ns ± 2%     197ns ± 1%  -37.08%  (p=0.008 n=5+5)

name        old alloc/op   new alloc/op   delta
GoString-8     80.0B ± 0%     80.0B ± 0%     ~     (all equal)

name        old allocs/op  new allocs/op  delta
GoString-8      1.00 ± 0%      1.00 ± 0%     ~     (all equal)

Fixes #54436

Change-Id: I8e6f8e7bbb9857b4bc0cdf6ed29a6b2415775db7
Reviewed-on: https://go-review.googlesource.com/c/go/+/423634
Run-TryBot: Joseph Tsai <joetsai@digital-static.net>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Joseph Tsai <joetsai@digital-static.net>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>

src/time/format.go
src/time/time_test.go

index 721a207c0ef3e312e4b1171c362a86586dfed429..80495c0266612ab109217913fffbb1a51648a37f 100644 (file)
@@ -540,26 +540,29 @@ func (t Time) String() string {
 // GoString implements fmt.GoStringer and formats t to be printed in Go source
 // code.
 func (t Time) GoString() string {
-       buf := make([]byte, 0, 70)
+       abs := t.abs()
+       year, month, day, _ := absDate(abs, true)
+       hour, minute, second := absClock(abs)
+
+       buf := make([]byte, 0, len("time.Date(9999, time.September, 31, 23, 59, 59, 999999999, time.Local)"))
        buf = append(buf, "time.Date("...)
-       buf = appendInt(buf, t.Year(), 0)
-       month := t.Month()
+       buf = appendInt(buf, year, 0)
        if January <= month && month <= December {
                buf = append(buf, ", time."...)
-               buf = append(buf, t.Month().String()...)
+               buf = append(buf, longMonthNames[month-1]...)
        } else {
                // It's difficult to construct a time.Time with a date outside the
                // standard range but we might as well try to handle the case.
                buf = appendInt(buf, int(month), 0)
        }
        buf = append(buf, ", "...)
-       buf = appendInt(buf, t.Day(), 0)
+       buf = appendInt(buf, day, 0)
        buf = append(buf, ", "...)
-       buf = appendInt(buf, t.Hour(), 0)
+       buf = appendInt(buf, hour, 0)
        buf = append(buf, ", "...)
-       buf = appendInt(buf, t.Minute(), 0)
+       buf = appendInt(buf, minute, 0)
        buf = append(buf, ", "...)
-       buf = appendInt(buf, t.Second(), 0)
+       buf = appendInt(buf, second, 0)
        buf = append(buf, ", "...)
        buf = appendInt(buf, t.Nanosecond(), 0)
        buf = append(buf, ", "...)
@@ -586,7 +589,7 @@ func (t Time) GoString() string {
                // case we hope not to hit too often.
                buf = append(buf, `time.Location(`...)
                buf = append(buf, []byte(quote(loc.name))...)
-               buf = append(buf, `)`...)
+               buf = append(buf, ')')
        }
        buf = append(buf, ')')
        return string(buf)
index 059c71bb8a07d1a736050ffa66fb3e06cf70775f..8ab79d3801832d4d3d0865271447a76f73641ea0 100644 (file)
@@ -1487,6 +1487,13 @@ func BenchmarkISOWeek(b *testing.B) {
        }
 }
 
+func BenchmarkGoString(b *testing.B) {
+       t := Now()
+       for i := 0; i < b.N; i++ {
+               _ = t.GoString()
+       }
+}
+
 func TestMarshalBinaryZeroTime(t *testing.T) {
        t0 := Time{}
        enc, err := t0.MarshalBinary()