From 1db82c3894ced3451f174bb56a43da026bdbd8ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Sun, 13 Oct 2024 00:58:10 +0000 Subject: [PATCH] perf: use strings.Cut, also strings.IndexByte more --- cht/log.go | 23 ++++++++++------------- cht/log_test.go | 18 +++++++++--------- proto/col_datetime64.go | 13 ++++++------- proto/col_enum.go | 10 ++++------ proto/col_map.go | 8 ++++---- proto/column.go | 8 ++++---- 6 files changed, 37 insertions(+), 43 deletions(-) diff --git a/cht/log.go b/cht/log.go index e059ce12..1294e7a9 100644 --- a/cht/log.go +++ b/cht/log.go @@ -17,17 +17,14 @@ type logInfo struct { // cut field between start and end, trimming space. // -// E.g. cut("[ 12345 ]", "[", "]") == "12345". -func cut(s, start, end string) string { - if s == "" || start == "" || end == "" { - return "" - } - left := strings.Index(s, start) +// E.g. cut("[ 12345 ]", '[', ']') == "12345". +func cut(s string, start, end byte) string { + left := strings.IndexByte(s, start) if left < 0 { return "" } s = s[left+1:] - right := strings.Index(s, end) + right := strings.IndexByte(s, end) if right < 0 { return "" } @@ -61,18 +58,18 @@ func (e LogEntry) Level() zapcore.Level { func parseLog(s string) LogEntry { s = strings.TrimSpace(s) - tid, _ := strconv.ParseUint(cut(s, "[", "]"), 10, 64) + tid, _ := strconv.ParseUint(cut(s, '[', ']'), 10, 64) var textStart int - if idx := strings.Index(s, "}"); idx > 0 { - textStart = strings.Index(s[idx:], ":") + idx + 1 + if idx := strings.IndexByte(s, '}'); idx > 0 { + textStart = strings.IndexByte(s[idx:], ':') + idx + 1 } if textStart-1 > len(s) { textStart = 0 } return LogEntry{ - QueryID: cut(s, "{", "}"), - Severity: cut(s, "<", ">"), - Name: cut(s, ">", ":"), + QueryID: cut(s, '{', '}'), + Severity: cut(s, '<', '>'), + Name: cut(s, '>', ':'), Message: strings.TrimSpace(s[textStart:]), ThreadID: tid, } diff --git a/cht/log_test.go b/cht/log_test.go index c834dd35..df3c5e22 100644 --- a/cht/log_test.go +++ b/cht/log_test.go @@ -10,44 +10,44 @@ func TestLog(t *testing.T) { t.Run("Cut", func(t *testing.T) { for _, tc := range []struct { Input string - Left string - Right string + Left byte + Right byte Output string }{ {}, { Input: "123214] [12345]][]", - Left: "[", Right: "]", + Left: '[', Right: ']', Output: "12345", }, { Input: "[ 591781 ] {} TCP-Session: b75e863b-c0c0-4b7b-b75e-863bc", - Left: "{", Right: "}", + Left: '{', Right: '}', Output: "", }, { Input: "[ 591781 ] {} TCP-Session: b75e863b-c0c0-4b7b-b75e-863bc", - Left: "<", Right: ">", + Left: '<', Right: '>', Output: "Debug", }, { Input: "2022.01.19 16:58:24.256488 [ 591781 ] {} ContextAccess (default): List of all grants including implicit", - Left: ">", Right: ":", + Left: '>', Right: ':', Output: "ContextAccess (default)", }, { Input: "{f9464441-7023-4df5-89e5-8d16ea6aa2dd} executeQuery: Read 2 rows, 204.00 B in 0.000814392 sec., 2455 rows/sec., 244.62 KiB/sec.", - Left: "{", Right: "}", + Left: '{', Right: '}', Output: "f9464441-7023-4df5-89e5-8d16ea6aa2dd", }, { Input: "[ 591781 ] {} TCP-Session: b75e863b-c0c0-4b7b-b75e-863bc", - Left: "[", Right: "]", + Left: '[', Right: ']', Output: "591781", }, } { if s := cut(tc.Input, tc.Left, tc.Right); s != tc.Output { - t.Errorf("cut(%s, %s, %s) %s != %s (expected)", + t.Errorf("cut(%s, %c, %c) %s != %s (expected)", tc.Input, tc.Left, tc.Right, s, tc.Output, ) } diff --git a/proto/col_datetime64.go b/proto/col_datetime64.go index f4d96a49..500d88b3 100644 --- a/proto/col_datetime64.go +++ b/proto/col_datetime64.go @@ -61,11 +61,10 @@ func (c *ColDateTime64) Infer(t ColumnType) error { if elem == "" { return errors.Errorf("invalid DateTime64: no elements in %q", t) } - elems := strings.SplitN(elem, ",", 2) - for i := range elems { - elems[i] = strings.Trim(elems[i], `' `) - } - n, err := strconv.ParseUint(elems[0], 10, 8) + pStr, locStr, hasloc := strings.Cut(elem, ",") + pStr = strings.Trim(pStr, `' `) + locStr = strings.Trim(locStr, `' `) + n, err := strconv.ParseUint(pStr, 10, 8) if err != nil { return errors.Wrap(err, "parse precision") } @@ -75,8 +74,8 @@ func (c *ColDateTime64) Infer(t ColumnType) error { } c.Precision = p c.PrecisionSet = true - if len(elems) > 1 { - loc, err := time.LoadLocation(elems[1]) + if hasloc { + loc, err := time.LoadLocation(locStr) if err != nil { return errors.Wrap(err, "invalid location") } diff --git a/proto/col_enum.go b/proto/col_enum.go index a4b4f249..f798ec90 100644 --- a/proto/col_enum.go +++ b/proto/col_enum.go @@ -63,14 +63,12 @@ func (e *ColEnum) parse(t ColumnType) error { for _, elem := range strings.Split(elements, ",") { def := strings.TrimSpace(elem) // 'hello' = 1 - parts := strings.SplitN(def, "=", 2) - if len(parts) != 2 { + left, right, hascomma := strings.Cut(def, "=") + if !hascomma { return errors.Errorf("bad enum definition %q", def) } - var ( - left = strings.TrimSpace(parts[0]) // 'hello' - right = strings.TrimSpace(parts[1]) // 1 - ) + left = strings.TrimSpace(left) // 'hello' + right = strings.TrimSpace(right) // 1 idx, err := strconv.Atoi(right) if err != nil { return errors.Errorf("bad right side of definition %q", right) diff --git a/proto/col_map.go b/proto/col_map.go index 956a9a8b..e27781dd 100644 --- a/proto/col_map.go +++ b/proto/col_map.go @@ -191,18 +191,18 @@ func (c ColMap[K, V]) Prepare() error { // Infer ensures Inferable column propagation. func (c *ColMap[K, V]) Infer(t ColumnType) error { - elems := strings.Split(string(t.Elem()), ",") - if len(elems) != 2 { + keytype, valtype, hascomma := strings.Cut(string(t.Elem()), ",") + if !hascomma || strings.ContainsRune(valtype, ',') { return errors.New("invalid map type") } if v, ok := c.Keys.(Inferable); ok { - ct := ColumnType(strings.TrimSpace(elems[0])) + ct := ColumnType(strings.TrimSpace(keytype)) if err := v.Infer(ct); err != nil { return errors.Wrap(err, "infer data") } } if v, ok := c.Values.(Inferable); ok { - ct := ColumnType(strings.TrimSpace(elems[1])) + ct := ColumnType(strings.TrimSpace(valtype)) if err := v.Infer(ct); err != nil { return errors.Wrap(err, "infer data") } diff --git a/proto/column.go b/proto/column.go index cc734234..0ac964a7 100644 --- a/proto/column.go +++ b/proto/column.go @@ -74,8 +74,8 @@ func (c ColumnType) Base() ColumnType { } var ( v = string(c) - start = strings.Index(v, "(") - end = strings.LastIndex(v, ")") + start = strings.IndexByte(v, '(') + end = strings.LastIndexByte(v, ')') ) if start <= 0 || end <= 0 || end < start { return c @@ -150,8 +150,8 @@ func (c ColumnType) Elem() ColumnType { } var ( v = string(c) - start = strings.Index(v, "(") - end = strings.LastIndex(v, ")") + start = strings.IndexByte(v, '(') + end = strings.LastIndexByte(v, ')') ) if start <= 0 || end <= 0 || end < start { // No element.