Skip to content

Commit b6519ad

Browse files
committed
Use mc.buf while interpolating
benchmark old ns/op new ns/op delta BenchmarkInterpolation 1900 1403 -26.16% benchmark old allocs new allocs delta BenchmarkInterpolation 2 1 -50.00% benchmark old bytes new bytes delta BenchmarkInterpolation 448 160 -64.29%
1 parent 96b3f4c commit b6519ad

File tree

2 files changed

+29
-15
lines changed

2 files changed

+29
-15
lines changed

benchmark_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ func BenchmarkInterpolation(b *testing.B) {
222222
},
223223
maxPacketAllowed: maxPacketSize,
224224
maxWriteSize: maxPacketSize - 1,
225+
buf: buffer{buf: make([]byte, defaultBufSize)},
225226
}
226227

227228
args := []driver.Value{

connection.go

+28-15
Original file line numberDiff line numberDiff line change
@@ -166,36 +166,49 @@ func (mc *mysqlConn) Prepare(query string) (driver.Stmt, error) {
166166
}
167167

168168
// estimateParamLength calculates upper bound of string length from types.
169-
func estimateParamLength(args []driver.Value) (int, bool) {
170-
l := 0
169+
func estimateParamLength(query string, args []driver.Value) (min, max int) {
170+
min = len(query)
171+
max = len(query)
171172
for _, a := range args {
173+
if a == nil {
174+
min += 4
175+
max += 4
176+
continue
177+
}
172178
switch v := a.(type) {
173179
case int64, float64:
174-
// 24 (-1.7976931348623157e+308) may be upper bound. But I'm not sure.
175-
l += 25
176-
case bool:
177-
l += 1 // 0 or 1
180+
min += 1
181+
max += 25 // 24 (-1.7976931348623157e+308) may be upper bound. But I'm not sure.
182+
case bool: // 0 or 1
183+
min += 1
184+
max += 1
178185
case time.Time:
179-
l += 30 // '1234-12-23 12:34:56.777777'
186+
min += 23 // '1234-12-23 12:34:56'
187+
max += 30 // '1234-12-23 12:34:56.777777'
180188
case string:
181-
l += len(v)*2 + 2
189+
min += len(v) + 2
190+
max += len(v)*2 + 2
182191
case []byte:
183-
l += len(v)*2 + 2
192+
min += len(v) + 2
193+
max += len(v)*2 + 2
184194
default:
185-
return 0, false
195+
panic("driver.Value has invalid type")
186196
}
187197
}
188-
return l, true
198+
return
189199
}
190200

191201
func (mc *mysqlConn) interpolateParams(query string, args []driver.Value) (string, error) {
192-
estimated, ok := estimateParamLength(args)
193-
if !ok {
202+
min, max := estimateParamLength(query, args)
203+
if min+4 > maxPacketSize { // 4 bytes for packet header
194204
return "", driver.ErrSkip
195205
}
196-
estimated += len(query)
206+
bufSize := max
207+
if max > maxPacketSize { // maxPacketSize is upper bound of mc.buffer
208+
bufSize = maxPacketSize
209+
}
197210

198-
buf := make([]byte, 0, estimated)
211+
buf := mc.buf.takeBuffer(bufSize)[:0]
199212
argPos := 0
200213

201214
for i := 0; i < len(query); i++ {

0 commit comments

Comments
 (0)