[PERF] PromQL: Split rangeEval for binary operations #16698
+185
−126
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Binary operations generally involve matching left-hand series against right-hand series, for which we had the
prepSeries
function pre-computing signatures.The genesis of this refactor is that I didn't understand what was going on in #9577, so I tried to simplify the code leading up to it.
But I got a bonus performance gain because
rangeEvalBinOp
passesVector
rather thanparser.Value
types to its evaluation function.Along the way, some other functions got extracted from
rangeEval
, and an annotation merge got hoisted.VectorAnd
,VectorOr
andVectorUnless
now return nilAnnotations
so they can be used directly as the evaluation function;VectorscalarBinop
should also returnAnnotations
but I'll leave that for another PR.Further work:
rangeEval
: two taking no expressions, one taking one, and one for function calls. Probably there are benefits to making each case less generic.rangeEvalBinOp
could compute series matches (via a map) once, and then use them over and over at each time step. This is not trivial as the same LHS can match different RHS as series come and go, but I think it will be a big win for large queries.rangeEvalBinOp
could implement the intended optimisation from Optimise VectorAnd for step invariant expression #9577 where one or other side is time-invariant.benchmark results
(
go test -timeout 50m -count=6 -run xxx -bench RangeQuery ./promql
)