Repository navigation
Release v0.33.0 #1581
TristonianJones
announced in
Announcements
Release v0.33.0
#1581
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
This release introduces a high-performance Pratt parser, a unified declarative cost model (
common/cost) with aggregate sizing and peak memory tracking, raw pointer traversal for native Go structs, and JSON/YAML parsing extensions, while eliminating quadratic type-checking bottlenecks.Features
EnablePrattParseroption (#1427, #1433, #1442, #1462, #1472, #1497, #1509, #1511, #1521)cel-cppwith iterative parenthesis handling, bounded expression nesting, and escaped function name support, delivering 8x–19x faster single-threaded parsing.common/cost),AggregateSizingStrategy, andCostModelVersion(#1430, #1435, #1441, #1474, #1478, #1482, #1512, #1519, #1525, #1537, #1548, #1556, #1558)cost.OverloadModelAST with containerKey/Elemsize propagation, aggregate sizing, value-backedElemOf/KeyOf/ElemTotal/KeyTotal/Lengthcombinators, and versioned compatibility viacel.CostModelVersion.cel.NativeTypesstruct field selection and presence checks viaunsafe.Pointeroffset traversal, adds generic Go slice/map adapters, and supports native type aliasing.json.parse,yaml.parse, andyaml.encodeextensions (returningoptional_typewith 10MB payload safety limits), alongsidebase64.encodeUrlandbase64.decodeUrlinext.Encoders.hasOnly,hasAny,hasAll, andhasExactlyinext.Lists,optional.hasValue(val)inOptionalTypesVersion(3), and single-evaluationoptMap/optFlatMapmacros inOptionalTypesVersion(4).ext/security/hmacwithhmac.digestand linear-time equality comparisons.Activation(#1483)cel.FunctionVarsbindings dynamically from the runtimeActivationorcel.Globals.cel.EnvJSON serialization (#1500, #1554)cel.Env.@blockcall tagging (#1467, #1544)common/astand tagscel.@blockcalls in compiled ASTs.fuzzing/.Fixes
O(N^2)type-checking latency and memory growth on long conjunctions (#1553).v0.32.0cost behavior atCostModelVersion(0)andv0.29.2cost limit error (#1571, #1572, #1573)EvalCancelledError("operation cancelled: actual cost limit exceeded") when runtime cost limits are exceeded and replaysv0.32.0static/runtime cost rules when pinned tocel.CostModelVersion(0).SafeSubtract,SafeTrunc, andSafeMultiplyByFactorTruncincommon/costsouint64and float-scaled costs saturate cleanly atmath.MaxUint64(includingNaN) and clamp negative values to0.Programevaluation and concurrent cost tracker race fix (#1480, #1484, #1486, #1488)Eval,ContextEval, andConcurrentEvalnil-safe, eliminates a data race when capturing cost trackers across goroutines, and removes time-based flakiness in interrupt checks.Foldabletwo-variable iteration.json:"-"tags andproto.ReflectMessagedereference (#1452, #1551, #1567)json:"-"skip tags on embedded Go structs, fixes JSON tag conversion inConvertToNative, and prevents invalid field dereferences overproto.ReflectMessage.Breaking Changes
There are no module path changes in this release, but callers relying on exact AST expansion shapes, golden cost estimates, or positional
SizeEstimateliterals should note:cel.CostModelVersion):cel.CostModelVersion(1)is now the default and tightens static/runtime cost bounds (propagating optional and container element sizes, charging1on absent optional qualifiers, and normalizing rational scale factors). Callers requiring exactv0.32.0cost compatibility can pincel.CostModelVersion(0).cel.OptionalTypes): Unpinnedcel.OptionalTypes()now defaults toOptionalTypesVersion(4), which wraps non-identifieroptMap/optFlatMaptargets in a single-evaluation comprehension (ComprehensionKind) rather than duplicating the target in a ternary call (CallKind), and includesoptional.hasValue(val)from v3. Pincel.OptionalTypes(cel.OptionalTypesVersion(2))to preserve legacy AST expansion and cost estimates.cost.SizeEstimateStruct Fields:cost.SizeEstimate(aliased bychecker.SizeEstimate) now includesKey *SizeEstimateandElem *SizeEstimatefields to track container element sizing. Unkeyed positional struct literals (SizeEstimate{0, 10}) must be updated to keyed literals (SizeEstimate{Min: 0, Max: 10}) orcost.FixedSizeEstimate/cost.RangedSizeEstimate.Notes on Performance
This release delivers major throughput and allocation improvements across all three phases of the CEL pipeline: parsing, type-checking, and evaluation.
Expected Impact
cel.EnablePrattParser(true)): Replacing ANTLR's reflection and DFA overhead with a custom recursive-descent Pratt parser and iterative parenthesis scanner ([Pratt parser] Add EnablePrattParser option and dual-mode testing #1433, [Pratt parser] Simplify helper methods and inlining #1442, Iteratively parse nested parentheses in Pratt parser #1509) speeds up single-threaded parsing by 7.4x–19.6x (and parallel parsing by 17x–38.7x) while cutting parser memory allocations by 8x–15x.O(N^2)CPU and heap growth when checking large conjunctions of macros or parameterized overloads, reducing 400-term conjunction checking from 1.46s / 882 MB to 7.1ms / 5.8 MB (-99.5%).unsafe.Pointerforcel.NativeTypes(Native raw pointer traversal for NativeType values #1515, Fix presence perf regression #1578) and routing optional proto3 field selections through precomputedfieldQualifierplans (Optimize optional struct field selections with fieldQualifier #1568) reduces struct access and presence test latency by 57%–78% and eliminates intermediate heap allocations onhas()checks.ExecutionFrameas a directActivation(Rearchitect ExecutionFrame to be a direct Activation #1489), flatteningdynamicSlotActivation.slotValsfrom[]*slotValto[]slotVal(Flatten dynamicSlotActivation.slotVals from []*slotVal to []slotVal #1569), lazily initializing standard/extension declarations (Lazily initialize standard library declarations and bindings #1501, Ensure extension and validator factories are lazily initialized #1502), and using generic slice lists (Generic slice list for improved type guarantees and speed #1498) reduce per-evaluation allocations across comprehension and block expressions.Go-lang Benchmark Citation (benchstat)
The performance improvements can be verified running the repository's native benchmark harness with benchstat:
name old time/op new time/op deltaBenchmarkByCategory/Simple (Pratt vs ANTLR) 325.2µs ± 2% 27.4µs ± 1% -91.57% (#1442)BenchmarkByCategory/Complex (Pratt vs ANTLR) 1179.7µs ± 2% 107.3µs ± 1% -90.90% (#1442)BenchmarkByCategory/Macros (Pratt vs ANTLR) 423.0µs ± 1% 50.5µs ± 1% -88.06% (#1442)BenchmarkByCategory/Errors (Pratt vs ANTLR) 1646.1µs ± 3% 83.8µs ± 1% -94.91% (#1442)BenchmarkCheckLongConjunction/terms=400 1460ms ± 2% 7.1ms ± 1% -99.51% (#1575)BenchmarkNativeTypes/PrimitiveFieldAccess 390ns ± 2% 100ns ± 1% -74.26% (#1515)BenchmarkNativeTypes/FieldPresence 320ns ± 2% 86ns ± 1% -73.25% (#1515)BenchmarkNativeTypes/NestedStructAccess 580ns ± 2% 125ns ± 1% -78.41% (#1515)BenchmarkInterpreter/select_pb3_optional_fields 463ns ± 1% 197ns ± 1% -57.42% (#1568)BenchmarkBlockEval 315ns ± 1% 268ns ± 1% -14.78% (#1569)name old allocs/op new allocs/op deltaBenchmarkByCategory/Simple (Pratt vs ANTLR) 1,646 ± 0% 404 ± 0% -75.46% (#1442)BenchmarkCheckLongConjunction/terms=400 882MB ± 0% 5.8MB ± 0% -99.34% (#1575, B/op)BenchmarkNativeTypes/PrimitiveFieldAccess 5.00 ± 0% 1.00 ± 0% -80.00% (#1515)BenchmarkNativeTypes/FieldPresence 4.00 ± 0% 0.00 ± 0% -100.00% (#1515)BenchmarkInterpreter/select_pb3_optional_fields 3.00 ± 0% 1.00 ± 0% -66.67% (#1568)BenchmarkBlockEval 8.00 ± 0% 5.00 ± 0% -37.50% (#1569)Full Changelog: v0.32.0...v0.33.0
This discussion was created from the release Release v0.33.0.
All reactions