Skip to content

Commit

Permalink
Optimize biunify for arrays (#7168)
Browse files Browse the repository at this point in the history
The construction of intermediate throwaway `ast.Array`s caused almost
5 million allocations when running `regal lint` against its own bundle.

While the results are likely more impressive for Regal policies than the
average one, this is still a substantial improvement across a large group
of policies.

**regal lint OPA main**
```
BenchmarkRegalLintingItself-10    1	3317838417 ns/op	6611412800 B/op	124873123 allocs/op
```

**regal lint this branch**
```
BenchmarkRegalLintingItself-10    1	3140384416 ns/op	6590159176 B/op	120098613 allocs/op
```

Signed-off-by: Anders Eknert <[email protected]>
  • Loading branch information
anderseknert authored Nov 11, 2024
1 parent 809dda2 commit c0fe200
Showing 1 changed file with 17 additions and 1 deletion.
18 changes: 17 additions & 1 deletion topdown/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,22 @@ func (e *eval) biunifyArraysRec(a, b *ast.Array, b1, b2 *bindings, iter unifyIte
})
}

func (e *eval) biunifyTerms(a, b []*ast.Term, b1, b2 *bindings, iter unifyIterator) error {
if len(a) != len(b) {
return nil
}
return e.biunifyTermsRec(a, b, b1, b2, iter, 0)
}

func (e *eval) biunifyTermsRec(a, b []*ast.Term, b1, b2 *bindings, iter unifyIterator, idx int) error {
if idx == len(a) {
return iter()
}
return e.biunify(a[idx], b[idx], b1, b2, func() error {
return e.biunifyTermsRec(a, b, b1, b2, iter, idx+1)
})
}

func (e *eval) biunifyObjects(a, b ast.Object, b1, b2 *bindings, iter unifyIterator) error {
if a.Len() != b.Len() {
return nil
Expand Down Expand Up @@ -1962,7 +1978,7 @@ func (e evalFunc) evalOneRule(iter unifyIterator, rule *ast.Rule, cacheKey ast.R

child.traceEnter(rule)

err := child.biunifyArrays(ast.NewArray(e.terms[1:]...), ast.NewArray(args...), e.e.bindings, child.bindings, func() error {
err := child.biunifyTerms(e.terms[1:], args, e.e.bindings, child.bindings, func() error {
return child.eval(func(child *eval) error {
child.traceExit(rule)

Expand Down

0 comments on commit c0fe200

Please sign in to comment.