Skip to content

chore: Optimize rego policy input allocations #6135

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

Merged
merged 8 commits into from
Feb 9, 2023

Conversation

Emyrk
Copy link
Member

@Emyrk Emyrk commented Feb 9, 2023

Manually convert to ast.Value instead of using generic json.Marshal conversion.

Saves ~0.1ms from all users with roles + groups.

Tests

The test TestRegoInputValue ensures there is no difference in the optimized output to the prior json.Marshal method. So this PR is 100% safe! 🥳

Results

Input allocations

This is the benchmark of just the saved allocations on the inputs.

JSONRegoValue was the previous method. ManualRegoValue is new technique.

33% reduction in the number of bytes allocated for a rather complex rbac subject. Actual savings depends on the actor and things like the number of groups they are in.

cpu: Intel(R) Core(TM) i7-6770HQ CPU @ 2.60GHz
BenchmarkRBACValueAllocation/ManualRegoValue-8             27673             42994 ns/op           17721 B/op        559 allocs/op
BenchmarkRBACValueAllocation/JSONRegoValue-8               10000            120974 ns/op           26494 B/op        700 allocs/op

Broader RBAC benchmark impact

Time savings are measurable! Not an order of magnitude, but it is faster.

Before

cpu: Intel(R) Core(TM) i7-6770HQ CPU @ 2.60GHz
BenchmarkRBACAuthorize/NoRoles-8            4432            304177 ns/op           81206 B/op       1582 allocs/op
BenchmarkRBACAuthorize/Admin-8              1821            873503 ns/op          183445 B/op       3826 allocs/op
BenchmarkRBACAuthorize/OrgAdmin-8                   1575            866685 ns/op          176617 B/op       3618 allocs/op
BenchmarkRBACAuthorize/OrgMember-8                  2232            651818 ns/op          140718 B/op       2997 allocs/op
BenchmarkRBACAuthorize/ManyRoles-8                  1226            997774 ns/op          235363 B/op       5074 allocs/op
BenchmarkRBACAuthorize/AdminWithScope-8             1836            763182 ns/op          179983 B/op       3742 allocs/op
BenchmarkRBACAuthorizeGroups/NoRolesGroupACL-8              3231            311936 ns/op           87965 B/op       1795 allocs/op
BenchmarkRBACAuthorizeGroups/AdminGroupACL-8                1543            746852 ns/op          197525 B/op       4250 allocs/op
BenchmarkRBACAuthorizeGroups/OrgAdminGroupACL-8             1681            931019 ns/op          192735 B/op       4086 allocs/op
BenchmarkRBACAuthorizeGroups/OrgMemberGroupACL-8            1315            882409 ns/op          198334 B/op       4224 allocs/op
BenchmarkRBACAuthorizeGroups/ManyRolesGroupACL-8            1310            932732 ns/op          252496 B/op       5366 allocs/op
BenchmarkRBACAuthorizeGroups/AdminWithScopeGroupACL-8       1462            691538 ns/op          197576 B/op       4250 allocs/op

After

cpu: Intel(R) Core(TM) i7-6770HQ CPU @ 2.60GHz
BenchmarkRBACAuthorize/NoRoles-8            3963            260746 ns/op           71624 B/op       1409 allocs/op
BenchmarkRBACAuthorize/Admin-8              1783            635798 ns/op          160946 B/op       3416 allocs/op
BenchmarkRBACAuthorize/OrgAdmin-8                   1828            632054 ns/op          155398 B/op       3245 allocs/op
BenchmarkRBACAuthorize/OrgMember-8                  2478            508771 ns/op          117930 B/op       2587 allocs/op
BenchmarkRBACAuthorize/ManyRoles-8                  1382            839324 ns/op          205169 B/op       4461 allocs/op
BenchmarkRBACAuthorize/AdminWithScope-8             1947            602195 ns/op          157378 B/op       3330 allocs/op
BenchmarkRBACAuthorizeGroups/NoRolesGroupACL-8              4207            250881 ns/op           74572 B/op       1519 allocs/op
BenchmarkRBACAuthorizeGroups/AdminGroupACL-8                2049            599757 ns/op          170143 B/op       3693 allocs/op
BenchmarkRBACAuthorizeGroups/OrgAdminGroupACL-8             1990            579503 ns/op          166293 B/op       3566 allocs/op
BenchmarkRBACAuthorizeGroups/OrgMemberGroupACL-8            2359            589980 ns/op          170074 B/op       3667 allocs/op
BenchmarkRBACAuthorizeGroups/ManyRolesGroupACL-8            1542            773863 ns/op          209250 B/op       4606 allocs/op
BenchmarkRBACAuthorizeGroups/AdminWithScopeGroupACL-8       1330           1155050 ns/op          170152 B/op       3693 allocs/op

Future work

If we implement ast.Value interface directly for our maps (eg roles), we can reduce a lot more allocations.

Emyrk added 2 commits February 9, 2023 10:21
Manually convert to ast.Value instead of using generic
json.Marshal conversion.
The optimized input is always compared to the normal json
marshal parser.
@Emyrk Emyrk marked this pull request as ready for review February 9, 2023 17:47
@Emyrk Emyrk requested a review from johnstcn February 9, 2023 17:47
@Emyrk Emyrk changed the title chore: Optimize rego policy evaluation allocations chore: Optimize rego policy input allocations Feb 9, 2023
@@ -79,6 +80,8 @@ var (
Site: permissions(map[string][]Action{
ResourceWildcard.Type: {WildcardSymbol},
}),
Org: map[string][]Permission{},
Copy link
Member

Choose a reason for hiding this comment

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

review: these had been breaking comparison due to comparing empty vs nil slice

Comment on lines +15 to +18
// Currently ast.Object.insert() is the slowest part of the process and allocates
// the most amount of bytes. This general approach copies all of our struct
// data and uses a lot of extra memory for handling things like sort order.
// A possible large improvement would be to implement the ast.Value interface directly.
Copy link
Member

Choose a reason for hiding this comment

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

👍

@Emyrk Emyrk merged commit af59e2b into main Feb 9, 2023
@Emyrk Emyrk deleted the stevenmasley/rego_less_alloc branch February 9, 2023 19:47
@github-actions github-actions bot locked and limited conversation to collaborators Feb 9, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants