Reduce alllocations done by the stack

This commit is contained in:
Vikram Rangnekar 2019-06-16 20:51:36 -04:00
parent 45c283f2a7
commit cd6d6f97a8
3 changed files with 36 additions and 37 deletions

View File

@ -1,7 +1,7 @@
goos: darwin goos: darwin
goarch: amd64 goarch: amd64
pkg: github.com/dosco/super-graph/psql pkg: github.com/dosco/super-graph/psql
BenchmarkCompile-8 100000 15246 ns/op 2823 B/op 53 allocs/op BenchmarkCompile-8 100000 15092 ns/op 3562 B/op 36 allocs/op
BenchmarkCompileParallel-8 300000 4559 ns/op 2848 B/op 53 allocs/op BenchmarkCompileParallel-8 300000 4684 ns/op 3592 B/op 36 allocs/op
PASS PASS
ok github.com/dosco/super-graph/psql 3.116s ok github.com/dosco/super-graph/psql 3.133s

View File

@ -390,16 +390,15 @@ func (com *Compiler) compileArgs(sel *Select, args []Arg) error {
return nil return nil
} }
func (com *Compiler) compileArgObj(arg *Arg) (*Exp, error) { func (com *Compiler) compileArgObj(st *util.Stack, arg *Arg) (*Exp, error) {
if arg.Val.Type != nodeObj { if arg.Val.Type != nodeObj {
return nil, fmt.Errorf("expecting an object") return nil, fmt.Errorf("expecting an object")
} }
return com.compileArgNode(arg.Val, true) return com.compileArgNode(st, arg.Val, true)
} }
func (com *Compiler) compileArgNode(node *Node, usePool bool) (*Exp, error) { func (com *Compiler) compileArgNode(st *util.Stack, node *Node, usePool bool) (*Exp, error) {
st := util.NewStack()
var root *Exp var root *Exp
if node == nil || len(node.Children) == 0 { if node == nil || len(node.Children) == 0 {
@ -521,9 +520,10 @@ func (com *Compiler) compileArgSearch(sel *Select, arg *Arg) error {
} }
func (com *Compiler) compileArgWhere(sel *Select, arg *Arg) error { func (com *Compiler) compileArgWhere(sel *Select, arg *Arg) error {
st := util.NewStack()
var err error var err error
ex, err := com.compileArgObj(arg) ex, err := com.compileArgObj(st, arg)
if err != nil { if err != nil {
return err return err
} }
@ -864,6 +864,7 @@ func pushChild(st *util.Stack, exp *Exp, node *Node) {
func compileFilter(filter []string) (*Exp, error) { func compileFilter(filter []string) (*Exp, error) {
var fl *Exp var fl *Exp
com := &Compiler{} com := &Compiler{}
st := util.NewStack()
if len(filter) == 0 { if len(filter) == 0 {
return &Exp{Op: OpNop}, nil return &Exp{Op: OpNop}, nil
@ -874,7 +875,7 @@ func compileFilter(filter []string) (*Exp, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
f, err := com.compileArgNode(node, false) f, err := com.compileArgNode(st, node, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -1,49 +1,47 @@
package util package util
type ( type Stack struct {
Stack struct { stA [20]interface{}
top *StackNode st []interface{}
length int top int
} }
StackNode struct {
value interface{}
prev *StackNode
}
)
// Create a new Stack // Create a new Stack
func NewStack() *Stack { func NewStack() *Stack {
return &Stack{nil, 0} s := &Stack{top: -1}
s.st = s.stA[:0]
return s
} }
// Return the number of items in the Stack // Return the number of items in the Stack
func (this *Stack) Len() int { func (s *Stack) Len() int {
return this.length return (s.top + 1)
} }
// View the top item on the Stack // View the top item on the Stack
func (this *Stack) Peek() interface{} { func (s *Stack) Peek() interface{} {
if this.length == 0 { if s.top == -1 {
return nil return -1
} }
return this.top.value return s.st[s.top]
} }
// Pop the top item of the Stack and return it // Pop the top item of the Stack and return it
func (this *Stack) Pop() interface{} { func (s *Stack) Pop() interface{} {
if this.length == 0 { if s.top == -1 {
return nil return -1
} }
n := this.top s.top--
this.top = n.prev return s.st[(s.top + 1)]
this.length--
return n.value
} }
// Push a value onto the top of the Stack // Push a value onto the top of the Stack
func (this *Stack) Push(value interface{}) { func (s *Stack) Push(value interface{}) {
n := &StackNode{value, this.top} s.top++
this.top = n if len(s.st) <= s.top {
this.length++ s.st = append(s.st, value)
} else {
s.st[s.top] = value
}
} }