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

Compilation latency dominated by addOverload operations when using extension libraries #519

Closed
jpbetz opened this issue Mar 22, 2022 · 5 comments
Assignees

Comments

@jpbetz
Copy link
Collaborator

jpbetz commented Mar 22, 2022

Originally found by @DangerOnTheRanger and @liggitt

In Kubernetes we use the same set of libraries for all CEL expressions, but have to pay the cost of registering them into an environment each time a CEL expression is compiled. This appears to dominate the compilation cost.

err = ce.Add(e.declarations...)

image

@jpbetz
Copy link
Collaborator Author

jpbetz commented Mar 22, 2022

@TristonianJones
Copy link
Collaborator

@jpbetz This doesn't surprise me. Why can't you use a statically configured environment?

@jpbetz
Copy link
Collaborator Author

jpbetz commented Mar 22, 2022

Why can't you use a statically configured environment?

Maybe we can? We vary the variable decls used across the compiled CEL expressions, which is what I think got us hung up here.

I'll have a look at #347 PR that you shared offline with me and see if that can be use to eliminate the bulk of the cost.

@TristonianJones
Copy link
Collaborator

TristonianJones commented Mar 23, 2022

@jpbetz Take a look at the draft state for #347. I've added some options to early validate declarations and to ensure that validated declarations are copied from one Env to the next when the Env.Extend() call is used.

This means that if you do an init() of the base environment for K8s you should see a 7-10x performance boost and a dramatic reduction in memory allocations:

func init() {
        // maybe panic if this errors
        baseEnv, _ = cel.NewEnv(
		cel.HomogeneousAggregateLiterals(),
                 library.ExtensionLibs...,
                 cel.EarlyValidateDeclarations(true),
	)
}

Then use the baseEnv.Extend with the per-compile options you need in your use case.

Before PR:

cpu: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
BenchmarkNewEnv-8   	     430	   2674244 ns/op	  574888 B/op	   20228 allocs/op

After PR:

cpu: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
BenchmarkNewEnv-8             	     994	   1064345 ns/op	  369540 B/op	   12238 allocs/op
BenchmarkEnvExtend-8          	    7965	    154726 ns/op	   42053 B/op	     661 allocs/op
BenchmarkEnvExtendNoDecls-8   	    9135	    114062 ns/op	   34511 B/op	     401 allocs/op

What do you think? If you think this will work, I'll finish up the tests tomorrow and we'll do another release. I'm actually tempted to make a base copy of the stdEnv internal to CEL to speed up the simple extension cases as well.

@jpbetz
Copy link
Collaborator Author

jpbetz commented Mar 24, 2022

Fixed by #347

See kubernetes/kubernetes#108954 for benchmarks.

@jpbetz jpbetz closed this as completed Mar 24, 2022
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

No branches or pull requests

2 participants