Skip to content

Commit

Permalink
Merge pull request denisenkom#635 from nussjustin/optimize-in
Browse files Browse the repository at this point in the history
Optimize In performance by reducing allocations for common queries
  • Loading branch information
jmoiron authored Jan 24, 2021
2 parents ded6c03 + 13b2331 commit 0bdc2a7
Showing 1 changed file with 17 additions and 8 deletions.
25 changes: 17 additions & 8 deletions bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,14 @@ func In(query string, args ...interface{}) (string, []interface{}, error) {
var flatArgsCount int
var anySlices bool

meta := make([]argMeta, len(args))
var stackMeta [32]argMeta

var meta []argMeta
if len(args) <= len(stackMeta) {
meta = stackMeta[:len(args)]
} else {
meta = make([]argMeta, len(args))
}

for i, arg := range args {
if a, ok := arg.(driver.Valuer); ok {
Expand Down Expand Up @@ -185,7 +192,9 @@ func In(query string, args ...interface{}) (string, []interface{}, error) {
}

newArgs := make([]interface{}, 0, flatArgsCount)
buf := make([]byte, 0, len(query)+len(", ?")*flatArgsCount)

var buf strings.Builder
buf.Grow(len(query) + len(", ?")*flatArgsCount)

var arg, offset int

Expand All @@ -211,10 +220,10 @@ func In(query string, args ...interface{}) (string, []interface{}, error) {
}

// write everything up to and including our ? character
buf = append(buf, query[:offset+i+1]...)
buf.WriteString(query[:offset+i+1])

for si := 1; si < argMeta.length; si++ {
buf = append(buf, ", ?"...)
buf.WriteString(", ?")
}

newArgs = appendReflectSlice(newArgs, argMeta.v, argMeta.length)
Expand All @@ -225,13 +234,13 @@ func In(query string, args ...interface{}) (string, []interface{}, error) {
offset = 0
}

buf = append(buf, query...)
buf.WriteString(query)

if arg < len(meta) {
return "", nil, errors.New("number of bindVars less than number arguments")
}

return string(buf), newArgs, nil
return buf.String(), newArgs, nil
}

func appendReflectSlice(args []interface{}, v reflect.Value, vlen int) []interface{} {
Expand All @@ -240,11 +249,11 @@ func appendReflectSlice(args []interface{}, v reflect.Value, vlen int) []interfa
args = append(args, val...)
case []int:
for i := range val {
args = append(args, val[i])
args = append(args, &val[i])
}
case []string:
for i := range val {
args = append(args, val[i])
args = append(args, &val[i])
}
default:
for si := 0; si < vlen; si++ {
Expand Down

0 comments on commit 0bdc2a7

Please sign in to comment.