Skip to content

Commit 9b7ffba

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 9b7ffba

File tree

3 files changed

+25
-17
lines changed

3 files changed

+25
-17
lines changed

benchmark_test.go

Lines changed: 1 addition & 0 deletions
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{

buffer.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ type buffer struct {
2525
}
2626

2727
func newBuffer(rd io.Reader) buffer {
28-
var b [defaultBufSize]byte
2928
return buffer{
30-
buf: b[:],
29+
buf: make([]byte, defaultBufSize),
3130
rd: rd,
3231
}
3332
}

connection.go

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -166,36 +166,44 @@ 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 {
172173
switch v := a.(type) {
173174
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
175+
min += 1
176+
max += 25 // 24 (-1.7976931348623157e+308) may be upper bound. But I'm not sure.
177+
case bool: // 0 or 1
178+
min += 1
179+
max += 1
178180
case time.Time:
179-
l += 30 // '1234-12-23 12:34:56.777777'
181+
min += 23 // '1234-12-23 12:34:56'
182+
max += 30 // '1234-12-23 12:34:56.777777'
180183
case string:
181-
l += len(v)*2 + 2
184+
min += len(v) + 2
185+
max += len(v)*2 + 2
182186
case []byte:
183-
l += len(v)*2 + 2
187+
min += len(v) + 2
188+
max += len(v)*2 + 2
184189
default:
185-
return 0, false
190+
panic("driver.Value has invalid type")
186191
}
187192
}
188-
return l, true
193+
return
189194
}
190195

191196
func (mc *mysqlConn) interpolateParams(query string, args []driver.Value) (string, error) {
192-
estimated, ok := estimateParamLength(args)
193-
if !ok {
197+
min, max := estimateParamLength(query, args)
198+
if min+4 > maxPacketSize { // 4 bytes for packet header
194199
return "", driver.ErrSkip
195200
}
196-
estimated += len(query)
201+
buffSize := max
202+
if max > maxPacketSize { // maxPacketSize is upper bound of mc.buffer
203+
buffSize = maxPacketSize
204+
}
197205

198-
buf := make([]byte, 0, estimated)
206+
buf := mc.buf.takeBuffer(buffSize)[:0]
199207
argPos := 0
200208

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

0 commit comments

Comments
 (0)