avoid repeated construction of cost tracker#1357
Conversation
Most fields in the CostTracker struct are only set once during construction. This takes a surprising amount of allocations, in particular for the overload map. Constructing the tracker once and cloning it for each evaluation avoids doing that work repeatedly. In a Kubernetes benchmark exercising (among other things) CEL expression evaluation, the cumulative CPU time and allocs for Eval dropped from 3.87s to 1.99s resp. from 3.85G to 2.1G.
|
/gcbrun |
|
@pohly Thanks for this change. Would you mind adding a test case that initiates initiates the cost tracking against a single compiled expression in a short loop to help prevent future regressions? |
|
How can such a test verify that Eval doesn't call NewCostTracker again? Just calling Eval multiple times will not fail, with or without this patch. |
|
It's purely defensive ... more that if something changes in the cost tracker in the future to make sure we don't miss the updates to |
|
A single Eval always uses NewCostTracker (during program construction) followed by Clone (when the factory function is called). But it doesn't hurt to do Eval more than once to cover the scenario that Clone is called more than once - will add something. |
Most fields in the CostTracker struct are only set once during construction. This takes a surprising amount of allocations, in particular for the overload map. Constructing the tracker once and cloning it for each evaluation avoids doing that work repeatedly.
In a Kubernetes benchmark exercising (among other things) CEL expression evaluation, the cumulative CPU time and allocs for Eval dropped from 3.87s to 1.99s resp. from 3.85G to 2.1G.