Skip to content

Commit

Permalink
topdown: Remove unnecessary allocations for binding undos
Browse files Browse the repository at this point in the history
The undo was being allocated on the heap unnecessarily. Removing the
heap allocation provides a slight speedup.

$ benchstat /tmp/old.txt /tmp/new.txt
name                      old time/op  new time/op  delta
ArrayIteration/10-20      24.7µs ± 1%  24.0µs ± 1%  -2.49%  (p=0.008n=5+5)
ArrayIteration/100-20      125µs ± 1%   122µs ± 1%  -2.88%  (p=0.008n=5+5)
ArrayIteration/1000-20    1.15ms ± 1%  1.12ms ± 1%  -2.66%  (p=0.008n=5+5)
ArrayIteration/10000-20   11.9ms ± 2%  11.6ms ± 1%  -2.52%  (p=0.008n=5+5)
SetIteration/10-20        28.3µs ± 1%  27.8µs ± 1%  -1.73%  (p=0.008n=5+5)
SetIteration/100-20        157µs ± 1%   154µs ± 1%  -1.81%  (p=0.008n=5+5)
SetIteration/1000-20      1.47ms ± 1%  1.44ms ± 1%  -2.00%  (p=0.008n=5+5)
SetIteration/10000-20     15.8ms ± 1%  16.0ms ± 4%    ~     (p=0.690n=5+5)
ObjectIteration/10-20     27.9µs ± 1%  27.8µs ± 1%    ~     (p=0.222n=5+5)
ObjectIteration/100-20     155µs ± 1%   152µs ± 1%  -1.96%  (p=0.016n=5+5)
ObjectIteration/1000-20   1.46ms ± 1%  1.44ms ± 1%  -1.73%  (p=0.008n=5+5)
ObjectIteration/10000-20  15.6ms ± 1%  15.2ms ± 2%  -2.50%  (p=0.016n=5+5)

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
  • Loading branch information
tsandall committed Dec 14, 2020
1 parent f9e0332 commit ef10c5f
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 9 deletions.
11 changes: 5 additions & 6 deletions topdown/bindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ import (
)

type undo struct {
k *ast.Term
u *bindings
next *undo
k *ast.Term
u *bindings
}

func (u *undo) Undo() {
Expand All @@ -27,7 +26,6 @@ func (u *undo) Undo() {
return
}
u.u.delete(u.k)
u.next.Undo()
}

type bindings struct {
Expand Down Expand Up @@ -123,12 +121,13 @@ func (u *bindings) plugNamespaced(a *ast.Term, caller *bindings) *ast.Term {
return a
}

func (u *bindings) bind(a *ast.Term, b *ast.Term, other *bindings) *undo {
func (u *bindings) bind(a *ast.Term, b *ast.Term, other *bindings, und *undo) {
u.values.Put(a, value{
u: other,
v: b,
})
return &undo{a, u, nil}
und.k = a
und.u = u
}

func (u *bindings) apply(a *ast.Term) (*ast.Term, *bindings) {
Expand Down
8 changes: 5 additions & 3 deletions topdown/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -800,21 +800,23 @@ func (e *eval) biunifyValues(a, b *ast.Term, b1, b2 *bindings, iter unifyIterato
_, varA := a.Value.(ast.Var)
_, varB := b.Value.(ast.Var)

var undo undo

if varA && varB {
if b1 == b2 && a.Equal(b) {
return iter()
}
undo := b1.bind(a, b, b2)
b1.bind(a, b, b2, &undo)
err := iter()
undo.Undo()
return err
} else if varA && !varB {
undo := b1.bind(a, b, b2)
b1.bind(a, b, b2, &undo)
err := iter()
undo.Undo()
return err
} else if varB && !varA {
undo := b2.bind(b, a, b1)
b2.bind(b, a, b1, &undo)
err := iter()
undo.Undo()
return err
Expand Down

0 comments on commit ef10c5f

Please sign in to comment.