Skip to content

Commit

Permalink
enhancement: Apply perf patch to YAML parser
Browse files Browse the repository at this point in the history
Update our fork with the performance patch from
goccy/go-yaml#438.

```
goos: linux
goarch: amd64
pkg: github.com/cerbos/cerbos/internal/parser
cpu: 13th Gen Intel(R) Core(TM) i7-1360P
                 │ parser_before.txt │          parser_after.txt           │
                 │      sec/op       │   sec/op     vs base                │
Unmarshal/10-16         3399.0µ ± 3%   847.2µ ± 4%  -75.08% (p=0.000 n=10)
Unmarshal/50-16         50.093m ± 7%   3.847m ± 2%  -92.32% (p=0.000 n=10)
Unmarshal/100-16       191.559m ± 6%   7.504m ± 3%  -96.08% (p=0.000 n=10)
Unmarshal/500-16       4674.56m ± 3%   35.09m ± 4%  -99.25% (p=0.000 n=10)
geomean                  111.1m        5.412m       -95.13%

                 │ parser_before.txt │             parser_after.txt              │
                 │        B/s        │      B/s        vs base                   │
Unmarshal/10-16         1.030Mi ± 3%     4.134Mi ± 4%    +301.39% (p=0.000 n=10)
Unmarshal/50-16         341.8Ki ± 6%    4423.8Ki ± 2%   +1194.29% (p=0.000 n=10)
Unmarshal/100-16        175.8Ki ± 6%    4506.8Ki ± 3%   +2463.89% (p=0.000 n=10)
Unmarshal/500-16        39.06Ki ± 0%   4794.92Ki ± 4%  +12175.00% (p=0.000 n=10)
geomean                 223.1Ki          4.380Mi        +1910.85%

                 │ parser_before.txt │           parser_after.txt           │
                 │       B/op        │     B/op      vs base                │
Unmarshal/10-16        4258.8Ki ± 0%   384.6Ki ± 0%  -90.97% (p=0.000 n=10)
Unmarshal/50-16        91.248Mi ± 0%   1.813Mi ± 0%  -98.01% (p=0.000 n=10)
Unmarshal/100-16      358.297Mi ± 0%   3.596Mi ± 0%  -99.00% (p=0.000 n=10)
Unmarshal/500-16      7944.51Mi ± 0%   18.98Mi ± 0%  -99.76% (p=0.000 n=10)
geomean                 181.3Mi        2.611Mi       -98.56%

                 │ parser_before.txt │          parser_after.txt           │
                 │     allocs/op     │  allocs/op   vs base                │
Unmarshal/10-16         10.595k ± 0%   8.978k ± 0%  -15.26% (p=0.000 n=10)
Unmarshal/50-16          50.64k ± 0%   42.93k ± 0%  -15.23% (p=0.000 n=10)
Unmarshal/100-16        100.83k ± 0%   85.38k ± 0%  -15.32% (p=0.000 n=10)
Unmarshal/500-16         505.9k ± 0%   425.6k ± 0%  -15.87% (p=0.000 n=10)
geomean                  72.33k        61.17k       -15.42%
```

Signed-off-by: Charith Ellawala <[email protected]>
  • Loading branch information
charithe committed May 2, 2024
1 parent eb6029c commit 0757c1b
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 5 deletions.
4 changes: 2 additions & 2 deletions cmd/cerbosctl/internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func GetAdminClient(globals *flagset.Globals) (*cerbos.GRPCAdminClient, error) {

opts := globals.ToClientOpts()

ac, err := cerbos.NewAdminClientWithCredentials(globals.Server, globals.Username, globals.Password, opts...)
ac, err := cerbos.NewAdminClientWithCredentials("passthrough:///"+globals.Server, globals.Username, globals.Password, opts...)
if err != nil {
return nil, fmt.Errorf("failed to create the admin client: %w", err)
}
Expand All @@ -36,7 +36,7 @@ func GetAdminClient(globals *flagset.Globals) (*cerbos.GRPCAdminClient, error) {
func GetClient(globals *flagset.Globals) (*cerbos.GRPCClient, error) {
opts := globals.ToClientOpts()

c, err := cerbos.New(globals.Server, opts...)
c, err := cerbos.New("passthrough:///"+globals.Server, opts...)
if err != nil {
return nil, fmt.Errorf("failed to create the client: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -301,4 +301,4 @@ require (
sigs.k8s.io/yaml v1.3.0 // indirect
)

replace github.com/goccy/go-yaml => github.com/cerbos/go-yaml v0.0.0-20240429140401-260886edbbb0
replace github.com/goccy/go-yaml => github.com/cerbos/go-yaml v0.0.0-20240502082720-ab3470c47ed6
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ github.com/cerbos/cerbos/api/genpb v0.35.1 h1:IgmvEUg+FXachWUT9f2b7NQ650kogwAEoe
github.com/cerbos/cerbos/api/genpb v0.35.1/go.mod h1:DcozdAIUztxXwtVs88gGgdyCITru7WCTF9vGA6j+H8k=
github.com/cerbos/cloud-api v0.1.18 h1:psD9psLgNq/u1IEOsp8L2mwwvB4umGeA4C4YHw19G9g=
github.com/cerbos/cloud-api v0.1.18/go.mod h1:Fv9gmVBEubgJ0H68wS2hVr69X+eS1W5PuaLUIM09umQ=
github.com/cerbos/go-yaml v0.0.0-20240429140401-260886edbbb0 h1:Wwhx45hzzYx8r1gBljgU0RcgdVQBwvSi+ORS49i+yhw=
github.com/cerbos/go-yaml v0.0.0-20240429140401-260886edbbb0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU=
github.com/cerbos/go-yaml v0.0.0-20240502082720-ab3470c47ed6 h1:GR4sGAsS8QtShlU7sGm2fNr7HXsnRUEXLVlkn21yjs4=
github.com/cerbos/go-yaml v0.0.0-20240502082720-ab3470c47ed6/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
Expand Down
68 changes: 68 additions & 0 deletions internal/parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"os"
"path/filepath"
"sort"
"strconv"
"strings"
"testing"
"time"
Expand All @@ -28,12 +29,14 @@ import (
"google.golang.org/protobuf/types/known/timestamppb"
"google.golang.org/protobuf/types/known/wrapperspb"

effectv1 "github.com/cerbos/cerbos/api/genpb/cerbos/effect/v1"
policyv1 "github.com/cerbos/cerbos/api/genpb/cerbos/policy/v1"
privatev1 "github.com/cerbos/cerbos/api/genpb/cerbos/private/v1"
sourcev1 "github.com/cerbos/cerbos/api/genpb/cerbos/source/v1"
"github.com/cerbos/cerbos/internal/namer"
"github.com/cerbos/cerbos/internal/parser"
"github.com/cerbos/cerbos/internal/test"
"github.com/cerbos/cerbos/internal/util"
)

func TestUnmarshal(t *testing.T) {
Expand Down Expand Up @@ -360,3 +363,68 @@ func walkAST(node ast.Node) ast.Visitor {
log.Printf("%s %s: %s -> %s", strings.Repeat(">", tok.Position.IndentNum+1), tok.Position, node.GetPath(), node.Type())
return astWalker(walkAST)
}

var Dummy uint64

func BenchmarkUnmarshal(b *testing.B) {
factory := func() *policyv1.Policy { return &policyv1.Policy{} }
benchCases := []struct {
policy *policyv1.Policy
numRules int
}{
{
numRules: 10,
policy: generatePolicy(b, 10),
},
{
numRules: 50,
policy: generatePolicy(b, 50),
},
{
numRules: 100,
policy: generatePolicy(b, 100),
},
{
numRules: 500,
policy: generatePolicy(b, 500),
},
}

for _, bc := range benchCases {
b.Run(strconv.Itoa(bc.numRules), func(b *testing.B) {
b.ReportAllocs()
for i := range b.N {
b.StopTimer()
bc.policy.Metadata = &policyv1.Metadata{
Annotations: map[string]string{"iteration": strconv.Itoa(i)},
Hash: wrapperspb.UInt64(rand.Uint64()),
}
buf := new(bytes.Buffer)
require.NoError(b, util.WriteYAML(buf, bc.policy))
b.SetBytes(int64(buf.Len()))
b.StartTimer()

policies, srcContexts, err := parser.Unmarshal(buf, factory)
require.NoError(b, err)
require.Len(b, policies, 1)
require.Len(b, srcContexts, 1)
Dummy |= bc.policy.GetMetadata().GetHash().GetValue()
}
})
}
}

func generatePolicy(b *testing.B, numRules int) *policyv1.Policy {
b.Helper()

pb := test.NewResourcePolicyBuilder("resource", "version")
pb = pb.WithDerivedRolesImports("a", "b", "c", "d", "e", "f")
for range numRules {
pb = pb.WithRules(test.NewResourceRule("create", "read", "update", "delete").
WithRoles("role_a", "role_b", "role_c", "role_d", "role_e").
WithMatchExpr("a == b", "c == d", "e == f", "g == h", "i == j").
WithEffect(effectv1.Effect_EFFECT_ALLOW).
Build())
}
return pb.Build()
}

0 comments on commit 0757c1b

Please sign in to comment.