Skip to content

Commit 50c9eab

Browse files
committed
optimistaions of quote functions by @sean-
1 parent 97d8358 commit 50c9eab

File tree

2 files changed

+42
-23
lines changed

2 files changed

+42
-23
lines changed

internal/sanitize/benchmmark.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ for i in "${!commits[@]}"; do
4343
}
4444

4545
# Sanitized commmit message
46-
commit_message=$(git log -1 --pretty=format:"%s" | tr ' ' '_')
46+
commit_message=$(git log -1 --pretty=format:"%s" | tr -c '[:alnum:]-_' '_')
4747

4848
# Benchmark data will go there
4949
bench_file="${benchmarks_dir}/${i}_${commit_message}.bench"
@@ -56,4 +56,5 @@ for i in "${!commits[@]}"; do
5656
bench_files+=("$bench_file")
5757
done
5858

59+
# go install golang.org/x/perf/cmd/benchstat[@latest]
5960
benchstat "${bench_files[@]}"

internal/sanitize/sanitize.go

+40-22
Original file line numberDiff line numberDiff line change
@@ -145,41 +145,59 @@ func (q *Query) init(sql string) {
145145
}
146146

147147
func QuoteString(dst []byte, str string) []byte {
148-
const quote = "'"
148+
const quote = '\''
149149

150-
n := strings.Count(str, quote)
150+
// Preallocate space for the worst case scenario
151+
dst = slices.Grow(dst, len(str)*2+2)
151152

152-
dst = append(dst, quote...)
153+
// Add opening quote
154+
dst = append(dst, quote)
153155

154-
p := slices.Grow(dst[len(dst):], 2*len(quote)+len(str)+2*n)
155-
156-
for len(str) > 0 {
157-
i := strings.Index(str, quote)
158-
if i < 0 {
159-
p = append(p, str...)
160-
break
156+
// Iterate through the string without allocating
157+
for i := 0; i < len(str); i++ {
158+
if str[i] == quote {
159+
dst = append(dst, quote, quote)
160+
} else {
161+
dst = append(dst, str[i])
161162
}
162-
p = append(p, str[:i]...)
163-
p = append(p, "''"...)
164-
str = str[i+1:]
165163
}
166164

167-
dst = append(dst, p...)
168-
169-
dst = append(dst, quote...)
165+
// Add closing quote
166+
dst = append(dst, quote)
170167

171168
return dst
172169
}
173170

174171
func QuoteBytes(dst, buf []byte) []byte {
175-
dst = append(dst, `'\x`...)
172+
if len(buf) == 0 {
173+
return append(dst, `'\x'`...)
174+
}
175+
176+
// Calculate required length
177+
requiredLen := 3 + hex.EncodedLen(len(buf)) + 1
178+
179+
// Ensure dst has enough capacity
180+
if cap(dst)-len(dst) < requiredLen {
181+
newDst := make([]byte, len(dst), len(dst)+requiredLen)
182+
copy(newDst, dst)
183+
dst = newDst
184+
}
185+
186+
// Record original length and extend slice
187+
origLen := len(dst)
188+
dst = dst[:origLen+requiredLen]
189+
190+
// Add prefix
191+
dst[origLen] = '\''
192+
dst[origLen+1] = '\\'
193+
dst[origLen+2] = 'x'
194+
195+
// Encode bytes directly into dst
196+
hex.Encode(dst[origLen+3:len(dst)-1], buf)
176197

177-
n := hex.EncodedLen(len(buf))
178-
p := slices.Grow(dst[len(dst):], n)[:n]
179-
hex.Encode(p, buf)
180-
dst = append(dst, p...)
198+
// Add suffix
199+
dst[len(dst)-1] = '\''
181200

182-
dst = append(dst, `'`...)
183201
return dst
184202
}
185203

0 commit comments

Comments
 (0)