Add object pooling for parser expressions

This commit is contained in:
Vikram Rangnekar 2019-06-15 01:10:53 -04:00
parent 340dea242d
commit 6b90b94e07
4 changed files with 57 additions and 14 deletions

7
psql/bench.5 Normal file
View File

@ -0,0 +1,7 @@
goos: darwin
goarch: amd64
pkg: github.com/dosco/super-graph/psql
BenchmarkCompile-8 100000 15728 ns/op 3000 B/op 60 allocs/op
BenchmarkCompileParallel-8 300000 5077 ns/op 3023 B/op 60 allocs/op
PASS
ok github.com/dosco/super-graph/psql 3.318s

View File

@ -657,10 +657,12 @@ func (c *compilerContext) renderWhere(sel *qcode.Select, ti *DBTableInfo) error
st.Push(val.Op) st.Push(val.Op)
} }
} }
qcode.FreeExp(val)
continue continue
case qcode.OpNot: case qcode.OpNot:
st.Push(val.Children[0]) st.Push(val.Children[0])
st.Push(qcode.OpNot) st.Push(qcode.OpNot)
qcode.FreeExp(val)
continue continue
} }
@ -669,6 +671,7 @@ func (c *compilerContext) renderWhere(sel *qcode.Select, ti *DBTableInfo) error
c.w.WriteString(`(("`) c.w.WriteString(`(("`)
c.w.WriteString(val.Col) c.w.WriteString(val.Col)
c.w.WriteString(`") `) c.w.WriteString(`") `)
} else if len(val.Col) != 0 { } else if len(val.Col) != 0 {
//fmt.Fprintf(w, `(("%s"."%s") `, c.sel.Table, val.Col) //fmt.Fprintf(w, `(("%s"."%s") `, c.sel.Table, val.Col)
c.w.WriteString(`((`) c.w.WriteString(`((`)
@ -757,9 +760,12 @@ func (c *compilerContext) renderWhere(sel *qcode.Select, ti *DBTableInfo) error
c.w.WriteString(`)`) c.w.WriteString(`)`)
} }
qcode.FreeExp(val)
default: default:
return fmt.Errorf("12: unexpected value %v (%t)", intf, intf) return fmt.Errorf("12: unexpected value %v (%t)", intf, intf)
} }
} }
return nil return nil

View File

@ -523,6 +523,6 @@ func (t parserType) String() string {
return fmt.Sprintf("<%s>", v) return fmt.Sprintf("<%s>", v)
} }
func PutNode(n *Node) { func FreeNode(n *Node) {
nodePool.Put(n) nodePool.Put(n)
} }

View File

@ -4,6 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"strings" "strings"
"sync"
"github.com/dosco/super-graph/util" "github.com/dosco/super-graph/util"
"github.com/gobuffalo/flect" "github.com/gobuffalo/flect"
@ -51,6 +52,13 @@ type Exp struct {
ListVal []string ListVal []string
Children []*Exp Children []*Exp
childrenA [5]*Exp childrenA [5]*Exp
doFree bool
}
var zeroExp = Exp{doFree: true}
func (ex *Exp) Reset() {
*ex = zeroExp
} }
type OrderBy struct { type OrderBy struct {
@ -141,6 +149,10 @@ type Compiler struct {
ka bool ka bool
} }
var expPool = sync.Pool{
New: func() interface{} { return new(Exp) },
}
func NewCompiler(c Config) (*Compiler, error) { func NewCompiler(c Config) (*Compiler, error) {
bl := make(map[string]struct{}, len(c.Blacklist)) bl := make(map[string]struct{}, len(c.Blacklist))
@ -385,10 +397,10 @@ func (com *Compiler) compileArgObj(arg *Arg) (*Exp, error) {
return nil, fmt.Errorf("expecting an object") return nil, fmt.Errorf("expecting an object")
} }
return com.compileArgNode(arg.Val) return com.compileArgNode(arg.Val, true)
} }
func (com *Compiler) compileArgNode(node *Node) (*Exp, error) { func (com *Compiler) compileArgNode(node *Node, usePool bool) (*Exp, error) {
st := util.NewStack() st := util.NewStack()
var root *Exp var root *Exp
@ -415,8 +427,7 @@ func (com *Compiler) compileArgNode(node *Node) (*Exp, error) {
} }
} }
ex, err := newExp(st, eT) ex, err := newExp(st, eT, usePool)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -459,7 +470,11 @@ func (com *Compiler) compileArgID(sel *Select, arg *Arg) error {
return nil return nil
} }
ex := &Exp{Op: OpEqID, Val: arg.Val.Val} ex := expPool.Get().(*Exp)
ex.Reset()
ex.Op = OpEqID
ex.Val = arg.Val.Val
switch arg.Val.Type { switch arg.Val.Type {
case nodeStr: case nodeStr:
@ -479,11 +494,12 @@ func (com *Compiler) compileArgID(sel *Select, arg *Arg) error {
} }
func (com *Compiler) compileArgSearch(sel *Select, arg *Arg) error { func (com *Compiler) compileArgSearch(sel *Select, arg *Arg) error {
ex := &Exp{ ex := expPool.Get().(*Exp)
Op: OpTsQuery, ex.Reset()
Type: ValStr,
Val: arg.Val.Val, ex.Op = OpTsQuery
} ex.Type = ValStr
ex.Val = arg.Val.Val
if sel.Where != nil { if sel.Where != nil {
ow := sel.Where ow := sel.Where
@ -643,7 +659,7 @@ func compileSub() (*Query, error) {
return nil, nil return nil, nil
} }
func newExp(st *util.Stack, eT *expT) (*Exp, error) { func newExp(st *util.Stack, eT *expT, usePool bool) (*Exp, error) {
node := eT.node node := eT.node
if len(node.Name) == 0 { if len(node.Name) == 0 {
@ -656,7 +672,15 @@ func newExp(st *util.Stack, eT *expT) (*Exp, error) {
name = name[1:] name = name[1:]
} }
ex := &Exp{} var ex *Exp
if usePool {
ex = expPool.Get().(*Exp)
ex.Reset()
} else {
ex = &Exp{}
}
ex.Children = ex.childrenA[:0]
switch name { switch name {
case "and": case "and":
@ -831,7 +855,7 @@ func compileFilter(filter []string) (*Exp, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
f, err := com.compileArgNode(node) f, err := com.compileArgNode(node, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -926,3 +950,9 @@ func (t ExpOp) String() string {
} }
return fmt.Sprintf("<%s>", v) return fmt.Sprintf("<%s>", v)
} }
func FreeExp(ex *Exp) {
if ex.doFree {
expPool.Put(ex)
}
}