Skip to content

Commit 5f859ba

Browse files
nussjustinbradfitz
authored andcommitted
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 <[email protected]> Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 2468227 commit 5f859ba

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

src/time/time.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -935,7 +935,12 @@ func (t Time) MarshalJSON() ([]byte, error) {
935935
// See golang.org/issue/4556#c15 for more discussion.
936936
return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]")
937937
}
938-
return []byte(t.Format(`"` + RFC3339Nano + `"`)), nil
938+
939+
b := make([]byte, 0, len(RFC3339Nano)+2)
940+
b = append(b, '"')
941+
b = t.AppendFormat(b, RFC3339Nano)
942+
b = append(b, '"')
943+
return b, nil
939944
}
940945

941946
// UnmarshalJSON implements the json.Unmarshaler interface.
@@ -952,7 +957,9 @@ func (t Time) MarshalText() ([]byte, error) {
952957
if y := t.Year(); y < 0 || y >= 10000 {
953958
return nil, errors.New("Time.MarshalText: year outside of range [0,9999]")
954959
}
955-
return []byte(t.Format(RFC3339Nano)), nil
960+
961+
b := make([]byte, 0, len(RFC3339Nano))
962+
return t.AppendFormat(b, RFC3339Nano), nil
956963
}
957964

958965
// UnmarshalText implements the encoding.TextUnmarshaler interface.

src/time/time_test.go

+14
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,20 @@ func BenchmarkFormatNow(b *testing.B) {
10601060
}
10611061
}
10621062

1063+
func BenchmarkMarshalJSON(b *testing.B) {
1064+
t := Now()
1065+
for i := 0; i < b.N; i++ {
1066+
t.MarshalJSON()
1067+
}
1068+
}
1069+
1070+
func BenchmarkMarshalText(b *testing.B) {
1071+
t := Now()
1072+
for i := 0; i < b.N; i++ {
1073+
t.MarshalText()
1074+
}
1075+
}
1076+
10631077
func BenchmarkParse(b *testing.B) {
10641078
for i := 0; i < b.N; i++ {
10651079
Parse(ANSIC, "Mon Jan 2 15:04:05 2006")

0 commit comments

Comments
 (0)