Skip to content

Lint performance Rego refactor#1857

Merged
anderseknert merged 1 commit intoopen-policy-agent:mainfrom
anderseknert:walk-perf-and-more
Feb 9, 2026
Merged

Lint performance Rego refactor#1857
anderseknert merged 1 commit intoopen-policy-agent:mainfrom
anderseknert:walk-perf-and-more

Conversation

@anderseknert
Copy link
Member

  • Rewrite walk calls that needed the path from the walk so that they no longer do. This is by far the most impactful change here, accounting for 90% of the reduces allocs
  • Inline and remove a few custom functions that only had a single dependent
  • Avoid count(x) == 0 and count(x) > 0 in favor of x == [] and x != [] (or "", set(), etc) when the type is known
  • Rewrite some count([x | some x in y]) == z constructs to instead use every
  • Avoid costly path in rule-length check (counting comments) if the rule length wasn't exceeded to begin with
  • Replace some i, x in y; i > 0 with some x in array.slice(y, 1, max) to avoid repeated gt call
  • Rewrite hot path function ref_to_string to allocate much less by calling less custom functions, and replacing an else condition with a map lookup

Reducing almost 1/4 of all memory (B/op) previously allocated!

BenchmarkRegalLintingItselfPrepareOnce

486491514 ns/op    1906786789 B/op    45640947 allocs/op // OPA v1.13.1 + fixes
420959403 ns/op    1534395760 B/op    36917131 allocs/op // Performance refactor

"boolean": `[%v]`,
}[part.type],
[part.value],
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Ewww

Copy link
Member Author

Choose a reason for hiding this comment

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

Lol, yes, but so much cheaper than branching with custom functions. Maybe one day it won't be 🥲

- Rewrite `walk` calls that needed the `path` from the walk so that they no longer do. This is by far the most impactful change here, accounting for 90% of the reduces allocs
- Inline and remove a few custom functions that only had a single dependent
- Avoid `count(x) == 0` and `count(x) > 0` in favor of `x == []` and `x != []` (or `""`, `set()`, etc) when the type is known
- Rewrite some `count([x | some x in y]) == z` constructs to instead use `every`
- Avoid costly path in rule-length check (counting comments) if the rule length wasn't exceeded to begin with
- Replace `some i, x in y; i > 0` with `some x in array.slice(y, 1, max)` to avoid repeated gt call
- Rewrite hot path function `ref_to_string`  to allocate much less by calling less custom functions, and replacing an `else` condition with a map lookup

Reducing almost 1/4 of all memory (B/op) previously allocated!

**BenchmarkRegalLintingItselfPrepareOnce**
```
486491514 ns/op    1906786789 B/op    45640947 allocs/op // OPA v1.13.1 + fixes
420959403 ns/op    1534395760 B/op    36917131 allocs/op // Performance refactor
```

Signed-off-by: Anders Eknert <anders.eknert@apple.com>
@anderseknert anderseknert merged commit 2bb2883 into open-policy-agent:main Feb 9, 2026
8 checks passed
@anderseknert anderseknert deleted the walk-perf-and-more branch February 9, 2026 12:15
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.

2 participants