Skip to content

Commit c4c1d5f

Browse files
authored
avoid fmt.Sprintf and string alloc for time.Sql (#2782)
* avoid fmt.Sprintf and string alloc for ttime.Sql * clean up printer code * clean up
1 parent dc32026 commit c4c1d5f

File tree

1 file changed

+46
-8
lines changed

1 file changed

+46
-8
lines changed

sql/types/time.go

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
package types
1616

1717
import (
18-
"fmt"
1918
"math"
2019
"reflect"
2120
"strconv"
@@ -263,7 +262,7 @@ func (t TimespanType_) Promote() sql.Type {
263262
}
264263

265264
// SQL implements Type interface.
266-
func (t TimespanType_) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltypes.Value, error) {
265+
func (t TimespanType_) SQL(_ *sql.Context, dest []byte, v interface{}) (sqltypes.Value, error) {
267266
if v == nil {
268267
return sqltypes.NULL, nil
269268
}
@@ -272,7 +271,7 @@ func (t TimespanType_) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltyp
272271
return sqltypes.Value{}, err
273272
}
274273

275-
val := AppendAndSliceString(dest, ti.String())
274+
val := AppendAndSliceBytes(dest, ti.Bytes())
276275

277276
return sqltypes.MakeTrusted(sqltypes.Time, val), nil
278277
}
@@ -463,15 +462,54 @@ func (t Timespan) timespanToUnits() (isNegative bool, hours int16, minutes int8,
463462

464463
// String returns the Timespan formatted as a string (such as for display purposes).
465464
func (t Timespan) String() string {
465+
return string(t.Bytes())
466+
}
467+
468+
func (t Timespan) Bytes() []byte {
466469
isNegative, hours, minutes, seconds, microseconds := t.timespanToUnits()
467-
sign := ""
470+
sz := 10
471+
if microseconds > 0 {
472+
sz += 7
473+
}
474+
ret := make([]byte, sz)
475+
i := 0
468476
if isNegative {
469-
sign = "-"
477+
ret[0] = '-'
478+
i++
479+
}
480+
481+
i = appendDigit(int64(hours), 2, ret, i)
482+
ret[i] = ':'
483+
i++
484+
i = appendDigit(int64(minutes), 2, ret, i)
485+
ret[i] = ':'
486+
i++
487+
i = appendDigit(int64(seconds), 2, ret, i)
488+
if microseconds > 0 {
489+
ret[i] = '.'
490+
i++
491+
i = appendDigit(int64(microseconds), 6, ret, i)
492+
}
493+
494+
return ret[:i]
495+
}
496+
497+
// appendDigit format prints 0-entended integer into buffer
498+
func appendDigit(v int64, extend int, buf []byte, i int) int {
499+
cmp := int64(1)
500+
for _ = range extend - 1 {
501+
cmp *= 10
502+
}
503+
for cmp > 0 && v < cmp {
504+
buf[i] = '0'
505+
i++
506+
cmp /= 10
470507
}
471-
if microseconds == 0 {
472-
return fmt.Sprintf("%v%02d:%02d:%02d", sign, hours, minutes, seconds)
508+
if v == 0 {
509+
return i
473510
}
474-
return fmt.Sprintf("%v%02d:%02d:%02d.%06d", sign, hours, minutes, seconds, microseconds)
511+
tmpBuf := strconv.AppendInt(buf[i:i], v, 10)
512+
return i + len(tmpBuf)
475513
}
476514

477515
// AsMicroseconds returns the Timespan in microseconds.

0 commit comments

Comments
 (0)