Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweaks to reduce number of allocations in regal lint hot path #7172

Merged
merged 1 commit into from
Nov 14, 2024

Conversation

anderseknert
Copy link
Member

Concluding my quest to reduce the number of allocations in the hot path for regal lint for this time around. This PR mainly does so by reusing pointers to boolean and integer terms where these are determined not to be mutated later.

The result is another ~4 million allocations reduced when linting Regal against its own bundle. These improvements should however help reduce allocations in pretty much any evaluation.

opa main

BenchmarkRegalLintingItself-10    1	3195257584 ns/op	6496097784 B/op	120108808 allocs/op

PR branch

BenchmarkRegalLintingItself-10    1	3132126333 ns/op	6376318224 B/op	116163318 allocs/op

ast/preload.go Outdated Show resolved Hide resolved
ast/preload.go Outdated Show resolved Hide resolved
srenatus
srenatus previously approved these changes Nov 13, 2024
Copy link
Contributor

@srenatus srenatus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are all great changes, thank you. I suppose I'd rather change the existing ast methods BooleanTerm and IntNumberTerm than add new functions, but it's not a strong opinion, I'd be curious whah @ash-styra and @johanfylling think about that.

@srenatus
Copy link
Contributor

Ran with benchstat, just for completeness...

goos: darwin
goarch: amd64
pkg: github.com/styrainc/regal/pkg/linter
cpu: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
                      │ main.bench  │      less-allocs.bench      │
                      │   sec/op    │   sec/op    vs base         │
RegalLintingItself-16   3.797 ± 10%   3.557 ± 8%  ~ (p=0.240 n=6)

                      │  main.bench  │         less-allocs.bench          │
                      │     B/op     │     B/op      vs base              │
RegalLintingItself-16   6.053Gi ± 0%   5.943Gi ± 0%  -1.83% (p=0.002 n=6)

                      │ main.bench  │         less-allocs.bench         │
                      │  allocs/op  │  allocs/op   vs base              │
RegalLintingItself-16   120.1M ± 0%   116.2M ± 0%  -3.28% (p=0.002 n=6)

@anderseknert
Copy link
Member Author

@srenatus existing functions are sometimes used like this:

body := NewBody(NewExpr(BooleanTerm(true).SetLocation(rhs.Location)).SetLocation(rhs.Location))

i.e mutating the pointer returned. If we want to have a single function to create bool/int terms, we'd have to at least identify all uses where mutation can happen after the pointer is returned. Having separate functions for cached values seemed like at least some way to try and communicate intent.

@srenatus
Copy link
Contributor

Ah right, these are terms! Yeah that makes sense, many of them will have a location. OK I'm convinced. I'm little on the fence about the "cached" terminology... a cache somehow carries the connotation that you can have a hit or a miss, or that something is cached for a while and then isn't. Would "Static" seem like a valid alternative? "Interned"? 🤔

@anderseknert
Copy link
Member Author

Interned sounds good to me! I'll make that change.

Concluding my quest to reduce the number of allocations in the
hot path for `regal lint` for this time around. This PR mainly
does so by reusing pointers to boolean and integer terms where
these are determined not to be mutated later.

The result is another ~4 million allocations reduced when
linting Regal against its own bundle. These improvements should
however help reduce allocations in pretty much any evaluation.

**opa main**
```
BenchmarkRegalLintingItself-10    1	3195257584 ns/op	6496097784 B/op	120108808 allocs/op
```

**PR branch**
```
BenchmarkRegalLintingItself-10    1	3132126333 ns/op	6376318224 B/op	116163318 allocs/op
```

Signed-off-by: Anders Eknert <[email protected]>
@srenatus
Copy link
Contributor

@ash-styra @johanfylling could you have a look, please? 😎

Copy link
Member

@ashutosh-narkar ashutosh-narkar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes look good. Few comments 👇

ast/interning.go Show resolved Hide resolved
ast/interning.go Show resolved Hide resolved
ast/parser.go Show resolved Hide resolved
Copy link
Contributor

@srenatus srenatus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's get this merged! 🥳

@srenatus srenatus merged commit d3f5102 into open-policy-agent:main Nov 14, 2024
28 checks passed
@anderseknert anderseknert deleted the less-allocs branch November 14, 2024 13:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants