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

Performance impact switching to some .. in iteration syntax #6740

Open
davidmarne-wf opened this issue May 7, 2024 · 2 comments
Open

Performance impact switching to some .. in iteration syntax #6740

davidmarne-wf opened this issue May 7, 2024 · 2 comments
Labels

Comments

@davidmarne-wf
Copy link
Contributor

davidmarne-wf commented May 7, 2024

Short description

There appears to be situations where some .. in iteration syntax is less performant than the legacy bracket syntax.

Examples:

all_operations contains operation if {
	role_allowed_operations[_][operation]
}
all_operations contains operation if {
	some role, operations in role_allowed_operations
	some operation in operations
}

I ran some benchmarks (see rego files attached for full policy), and i'm seeing a noticeable changes in eval times

  • p99 ~1000000ns to 500000ns
  • p95 ~ 460000ns to to 32716ns

Steps To Reproduce

  1. download the 2 rego files attached and rename from .txt to .rego
  2. run ./opa bench --data issue_case_1.rego 'data.issue.operation_exists'
  3. run ./opa bench --data issue_case_2.rego 'data.issue.operation_exists'
  4. compare the eval time for each, the first use case should be much slower

issue_case_1.txt
issue_case_2.txt

Expected behavior

Performance should be equivalent in issue_case_1 & issue_case_2

Additional context

The iteration here is a fairly complex type of map<string, set<tuple<string, string>>>

@anderseknert
Copy link
Member

Good find!

Looking at the output from the compiler (using opa-explorer), the nested iteration is left intact, while the some .. in loops are rewritten to something like this:

all_operations contains operation if {
    allowed_operation := role_allowed_operations[_]
    operation := allowed_operation[_]
}

Which seems to have the same negative impact compared to nesting the loop. I'd guess it's got something to do with all the intermediate values having to be realized on the "Rego side", but someone else (@johanfylling?) likely knows better :) If that is the case, it would be nice if the compiler could identify sequences of some .. in iteration and rewrite them to a single nested iteration where possible.

(btw, I think "more performant" should be "less performant" in the description 🙂)

@johanfylling
Copy link
Contributor

I can confirm that evaluation of the "short-form" enumeration role_allowed_operations[_][operation] is slightly different, and it' wouldn't surprise me if this has a performance impact.
As @anderseknert suggests, I think it should be possible to detect this at compile-time (at least trivial cases), and optimize accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants