From: Justin Nuß Date: Sun, 31 May 2015 11:17:59 +0000 (+0200) Subject: time: Use AppendFormat in Marshal[Text|JSON] X-Git-Tag: go1.6beta1~1300 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=5f859ba83d4c47b6a6a75559041207387acab7ba;p=gostls13.git time: Use AppendFormat in Marshal[Text|JSON] The current implementations of MarshalJSON and MarshalText use time.Format which returns a string (converted from a byte slice), only to convert it back to a byte slice. Avoid the conversion (and thus an allocation) by directly appending the formatted time to a preallocated byte slice, using the new AppendFormat function, introduced in golang.org/cl/1760. This reduces the allocations done in Marshal[Text|JSON] by 50%. benchmark old ns/op new ns/op delta BenchmarkMarshalJSON 626 507 -19.01% BenchmarkMarshalText 598 511 -14.55% benchmark old allocs new allocs delta BenchmarkMarshalJSON 2 1 -50.00% BenchmarkMarshalText 2 1 -50.00% benchmark old bytes new bytes delta BenchmarkMarshalJSON 96 48 -50.00% BenchmarkMarshalText 96 48 -50.00% Fixes #11025 Change-Id: I468f78d075a6ecc1cdc839df7fb407fbc6ff2e70 Reviewed-on: https://go-review.googlesource.com/10555 Reviewed-by: Brad Fitzpatrick Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- diff --git a/src/time/time.go b/src/time/time.go index 294cc77f41..c78c80c43b 100644 --- a/src/time/time.go +++ b/src/time/time.go @@ -935,7 +935,12 @@ func (t Time) MarshalJSON() ([]byte, error) { // See golang.org/issue/4556#c15 for more discussion. return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]") } - return []byte(t.Format(`"` + RFC3339Nano + `"`)), nil + + b := make([]byte, 0, len(RFC3339Nano)+2) + b = append(b, '"') + b = t.AppendFormat(b, RFC3339Nano) + b = append(b, '"') + return b, nil } // UnmarshalJSON implements the json.Unmarshaler interface. @@ -952,7 +957,9 @@ func (t Time) MarshalText() ([]byte, error) { if y := t.Year(); y < 0 || y >= 10000 { return nil, errors.New("Time.MarshalText: year outside of range [0,9999]") } - return []byte(t.Format(RFC3339Nano)), nil + + b := make([]byte, 0, len(RFC3339Nano)) + return t.AppendFormat(b, RFC3339Nano), nil } // UnmarshalText implements the encoding.TextUnmarshaler interface. diff --git a/src/time/time_test.go b/src/time/time_test.go index 2d16ea59ae..a925e98a83 100644 --- a/src/time/time_test.go +++ b/src/time/time_test.go @@ -1060,6 +1060,20 @@ func BenchmarkFormatNow(b *testing.B) { } } +func BenchmarkMarshalJSON(b *testing.B) { + t := Now() + for i := 0; i < b.N; i++ { + t.MarshalJSON() + } +} + +func BenchmarkMarshalText(b *testing.B) { + t := Now() + for i := 0; i < b.N; i++ { + t.MarshalText() + } +} + func BenchmarkParse(b *testing.B) { for i := 0; i < b.N; i++ { Parse(ANSIC, "Mon Jan 2 15:04:05 2006")