From a9859a7df72a8ca9686b4fb939989c04b42804fe Mon Sep 17 00:00:00 2001 From: Joe Tsai Date: Thu, 17 Aug 2023 18:13:01 -0700 Subject: [PATCH] time: make Duration.String inlineable Perform the [32]byte to string conversion in an inlinable method. Thus, if the result does not escape in the context of the caller, we can entirely avoid a call to runtime.slicebytetostring. Change-Id: Iae8ec2a532776ed6cf99597f19e3f7f21c694c3a Reviewed-on: https://go-review.googlesource.com/c/go/+/520602 Run-TryBot: Joseph Tsai Reviewed-by: Matthew Dempsky TryBot-Result: Gopher Robot Run-TryBot: Ian Lance Taylor Auto-Submit: Joseph Tsai Reviewed-by: Ian Lance Taylor --- src/time/time.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/time/time.go b/src/time/time.go index 8570635e2a..cc9dd6652a 100644 --- a/src/time/time.go +++ b/src/time/time.go @@ -650,8 +650,17 @@ const ( // second format use a smaller unit (milli-, micro-, or nanoseconds) to ensure // that the leading digit is non-zero. The zero duration formats as 0s. func (d Duration) String() string { + // This is inlinable to take advantage of "function outlining". + // Thus, the caller can decide whether a string must be heap allocated. + var arr [32]byte + n := d.format(&arr) + return string(arr[n:]) +} + +// format formats the representation of d into the end of buf and +// returns the offset of the first character. +func (d Duration) format(buf *[32]byte) int { // Largest time is 2540400h10m10.000000000s - var buf [32]byte w := len(buf) u := uint64(d) @@ -669,7 +678,8 @@ func (d Duration) String() string { w-- switch { case u == 0: - return "0s" + buf[w] = '0' + return w case u < uint64(Microsecond): // print nanoseconds prec = 0 @@ -719,7 +729,7 @@ func (d Duration) String() string { buf[w] = '-' } - return string(buf[w:]) + return w } // fmtFrac formats the fraction of v/10**prec (e.g., ".12345") into the -- 2.50.0