forked from open-policy-agent/opa
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Perf: improvements to terms and built-in functions (open-policy-agent…
…#7284) Having worked on performance improvements in OPA on the side for almost a month now, there's a lot of code piling up 😅 So much that a single PR would be way too much to review. Instead, I'm splitting the work into chunks, and will submit the next PR as soon as this one is merged. Using the same benchmark as before — Regal linting itself, these new changes in total reduce the number of allocations by ~13 million, and quite a substantial amount of evaluation time saved as well. This first PR is isolated to improvements to terms, values and built-ins, and saves ~3M allocations. The details can be found below for each change, and of course in the code :) **BenchmarkRegalLintingItself-10 Before** ``` 1885978209 ns/op 3497157312 B/op 69064779 allocs/op ``` **BenchmarkRegalLintingItself-10 After** ``` 1796255084 ns/op 3452379408 B/op 66126623 allocs/op ``` **Terms** - Use pointer receivers consistently for object and set types. This allows changing the sortGuard once lock from a pointer to a non-pointer type, which is really the biggest win performance-wise in this PR. - Comparisons happen all the time, so make sure these take the shortest path possible whenever, possible, such as when one type is compared to another value of the same type. Built-in functions: **Arrays** - Both `array.concat` and `array.slice` will now return the operand on operations where the result isn't different from the input operand (like when concatenating an empty array) instead of allocating a new term/value. **Strings** - Return operand on unchanged result rather than allocating new term/value. - Where applicable, have functions take a cheaper path when string is ASCII and we can avoid the cost of rune conversion. **Crypto** - Hashing functions now optimized, spending less than half the time compared to previously. **Objects** - Avoid heap allocating result boolean escaping its scope, and instead use the return value of the `Until` function. **HTTP** - Use interned terms for keys in configuration object, avoding allocating these each time `http.send` is invoked. **Globs** - Use read/write lock to avoid contention. Use package level vars for "constant" values, avoiding them to escape to the heap each invocation. **Not directly/only related to built-in functions** - Add `ValueName` function replacing the previous `TypeName` functions for getting the name of Value's without paying for `any` interface allocations. - Add a few more interned terms. Signed-off-by: Anders Eknert <anders@styra.com>
- Loading branch information
1 parent
304768b
commit 75962f5
Showing
29 changed files
with
634 additions
and
304 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package ast | ||
|
||
import "testing" | ||
|
||
// BenchmarkTypeName-10 32207775 38.93 ns/op 8 B/op 1 allocs/op | ||
func BenchmarkTypeName(b *testing.B) { | ||
term := StringTerm("foo") | ||
b.ResetTimer() | ||
|
||
for i := 0; i < b.N; i++ { | ||
name := TypeName(term.Value) | ||
if name != "string" { | ||
b.Fatalf("expected string but got %v", name) | ||
} | ||
} | ||
} | ||
|
||
// BenchmarkValueName-10 508312227 2.374 ns/op 0 B/op 0 allocs/op | ||
func BenchmarkValueName(b *testing.B) { | ||
term := StringTerm("foo") | ||
b.ResetTimer() | ||
|
||
for i := 0; i < b.N; i++ { | ||
name := ValueName(term.Value) | ||
if name != "string" { | ||
b.Fatalf("expected string but got %v", name) | ||
} | ||
} | ||
} |
Oops, something went wrong.