From cd6d6f97a8f765134a56385ad7737a5b35734671 Mon Sep 17 00:00:00 2001 From: Vikram Rangnekar Date: Sun, 16 Jun 2019 20:51:36 -0400 Subject: [PATCH] Reduce alllocations done by the stack --- psql/bench.8 | 6 +++--- qcode/qcode.go | 13 ++++++------ util/stack.go | 54 ++++++++++++++++++++++++-------------------------- 3 files changed, 36 insertions(+), 37 deletions(-) diff --git a/psql/bench.8 b/psql/bench.8 index 014931c..d42c64f 100644 --- a/psql/bench.8 +++ b/psql/bench.8 @@ -1,7 +1,7 @@ goos: darwin goarch: amd64 pkg: github.com/dosco/super-graph/psql -BenchmarkCompile-8 100000 15246 ns/op 2823 B/op 53 allocs/op -BenchmarkCompileParallel-8 300000 4559 ns/op 2848 B/op 53 allocs/op +BenchmarkCompile-8 100000 15092 ns/op 3562 B/op 36 allocs/op +BenchmarkCompileParallel-8 300000 4684 ns/op 3592 B/op 36 allocs/op PASS -ok github.com/dosco/super-graph/psql 3.116s +ok github.com/dosco/super-graph/psql 3.133s diff --git a/qcode/qcode.go b/qcode/qcode.go index d61519d..0335482 100644 --- a/qcode/qcode.go +++ b/qcode/qcode.go @@ -390,16 +390,15 @@ func (com *Compiler) compileArgs(sel *Select, args []Arg) error { 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 { 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) { - st := util.NewStack() +func (com *Compiler) compileArgNode(st *util.Stack, node *Node, usePool bool) (*Exp, error) { var root *Exp 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 { + st := util.NewStack() var err error - ex, err := com.compileArgObj(arg) + ex, err := com.compileArgObj(st, arg) if err != nil { return err } @@ -864,6 +864,7 @@ func pushChild(st *util.Stack, exp *Exp, node *Node) { func compileFilter(filter []string) (*Exp, error) { var fl *Exp com := &Compiler{} + st := util.NewStack() if len(filter) == 0 { return &Exp{Op: OpNop}, nil @@ -874,7 +875,7 @@ func compileFilter(filter []string) (*Exp, error) { if err != nil { return nil, err } - f, err := com.compileArgNode(node, false) + f, err := com.compileArgNode(st, node, false) if err != nil { return nil, err } diff --git a/util/stack.go b/util/stack.go index 06f5709..fd88f3e 100644 --- a/util/stack.go +++ b/util/stack.go @@ -1,49 +1,47 @@ package util -type ( - Stack struct { - top *StackNode - length int - } - StackNode struct { - value interface{} - prev *StackNode - } -) +type Stack struct { + stA [20]interface{} + st []interface{} + top int +} // Create a new 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 -func (this *Stack) Len() int { - return this.length +func (s *Stack) Len() int { + return (s.top + 1) } // View the top item on the Stack -func (this *Stack) Peek() interface{} { - if this.length == 0 { - return nil +func (s *Stack) Peek() interface{} { + if s.top == -1 { + return -1 } - return this.top.value + return s.st[s.top] } // Pop the top item of the Stack and return it -func (this *Stack) Pop() interface{} { - if this.length == 0 { - return nil +func (s *Stack) Pop() interface{} { + if s.top == -1 { + return -1 } - n := this.top - this.top = n.prev - this.length-- - return n.value + s.top-- + return s.st[(s.top + 1)] } // Push a value onto the top of the Stack -func (this *Stack) Push(value interface{}) { - n := &StackNode{value, this.top} - this.top = n - this.length++ +func (s *Stack) Push(value interface{}) { + s.top++ + if len(s.st) <= s.top { + s.st = append(s.st, value) + } else { + s.st[s.top] = value + } }