Skip to content

Commit

Permalink
Merge pull request #2979 from rockwotj/microbench
Browse files Browse the repository at this point in the history
  • Loading branch information
rockwotj authored Nov 7, 2024
2 parents ad34c85 + 1dbc1c6 commit 807a004
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
34 changes: 33 additions & 1 deletion internal/impl/snowflake/streaming/compat.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"strconv"
"strings"
"time"
"unicode/utf8"

"github.com/redpanda-data/connect/v4/internal/impl/snowflake/streaming/int128"
)
Expand Down Expand Up @@ -147,7 +148,38 @@ func normalizeColumnName(name string) string {
}
// fallthrough
}
return strings.ToUpper(strings.ReplaceAll(name, `\ `, ` `))
// Add a fast path if there is no escaping note that this is an optimized version of
// strings.ToUpper(strings.ReplaceAll(name, `\ `, ` `))
// which indeed we fallback to that if we get unicode or any escaped spaces.

// First check to see if the name is already normalized, in that case we can save
// an alloc however most strings I assume are in snake or camel casing so those
// will likely just check the first byte in this loop then bail, so this extra
// loop allows for still optimizing performance over just calling into the stdlib.
hasLower := false
for _, c := range []byte(name) {
if 'a' <= c && c <= 'z' {
hasLower = true
break // must alloc
} else if c >= utf8.RuneSelf || c == '\\' {
// Fallback
return strings.ToUpper(strings.ReplaceAll(name, `\ `, ` `))
}
}
if !hasLower {
return name
}
transformed := []byte(name)
for i, c := range transformed {
if 'a' <= c && c <= 'z' {
c -= 'a' - 'A'
transformed[i] = c
} else if c >= utf8.RuneSelf || c == '\\' {
// Fallback
return strings.ToUpper(strings.ReplaceAll(name, `\ `, ` `))
}
}
return string(transformed)
}

// quoteColumnName escapes an object identifier according to the
Expand Down
20 changes: 20 additions & 0 deletions internal/impl/snowflake/streaming/compat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"encoding/base64"
"encoding/hex"
"slices"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -127,6 +128,25 @@ func TestColumnNormalization(t *testing.T) {
require.Equal(t, `foo" bar "baz`, normalizeColumnName(`"foo"" bar ""baz"`))
}

func BenchmarkColumnNormalization(b *testing.B) {
makeBench := func(name string) func(b *testing.B) {
return func(b *testing.B) {
var normalized string
for i := 0; i < b.N; i++ {
normalized = normalizeColumnName(name)
}
b.SetBytes(int64(len(normalized)))
}
}
b.Run("snake_case", makeBench("foo_bar"))
b.Run("camelCase", makeBench("fooBar"))
b.Run("upper", makeBench("FOOBAR"))
b.Run("small", makeBench("a"))
b.Run("large", makeBench(strings.Repeat("a", 128)))
// Appently this is German for "fuel oil recoil absorber"
b.Run("unicode", makeBench("heizölrückstoßabdämpfung"))
}

func TestColumnQuoting(t *testing.T) {
require.Equal(t, `""`, quoteColumnName(""))
require.Equal(t, `"FOO"`, quoteColumnName("foo"))
Expand Down

0 comments on commit 807a004

Please sign in to comment.