Uh oh!
There was an error while loading. Please reload this page.
Impl convert_to_state for GroupsAccumulatorAdapter (faster median for high cardinality aggregates) - #11827
Conversation
| self.allocation_bytes | ||
| } | ||
| fn convert_to_state( |
There was a problem hiding this comment.
thanks @Rachelint
This might be interesting to you: #11825
There was a problem hiding this comment.
thanks @Rachelint
This might be interesting to you: #11825
Seems interesting, learning this pr (still not so familiar with arrow ops).
There was a problem hiding this comment.
Yeah, it takes some getting used to thinking in terms of Arrays and masks, etc
There was a problem hiding this comment.
Sorry for delay, fixed.
There was a problem hiding this comment.
Found the quick way using filtered_null_mask + set_nulls will just set the filtered row to be null, but not change the row num.
// `filtered_null_mask` + `set_nulls`
left:PrimitiveArray<Int32>
[
null,
null,6,
null,
null,
null,]// `compute::filter`
right:PrimitiveArray<Int32>
[
null,6,]Maybe this will make difference to the correctness for some accumulators? For example, an udf count which thinks a null row as 1?
f29d0bb to
76f5abaCompare76f5aba to
be5316fComparebe5316f to
0396fc4Comparefc2a0b5 to
179f8f8Compare
alamb
left a comment
There was a problem hiding this comment.
Thank you @Rachelint -- this looks very cool . I am sorry for the delay in the review
It is my understanding that this will allow aggregates that do not yet implement GroupsAccumulator to benefit from the intermediate aggregate state.
Thus the primary benefit of this code is to make aggregates on such queries faster.
Unfortunately I don't think we have any examples of such aggregates in the benchmarks (e.g. calculating median or approx_median). I will make a PR to add some to see if we can measure improvement of this PR
cc @korowa
Rachelint
commented
Sep 11, 2024
Sounds great! And we can continue to improve the performance after having such benchmarks. |
alamb
commented
Sep 11, 2024
I created a proposal in #12438 I tested a little locally on the PR here and it seems like this PR does not improve the performance much. |
Rachelint
commented
Sep 11, 2024
Ok, I will check it in my local soon. |
alamb
commented
Sep 11, 2024
It may be that the query doesn't show the correct pattern of high cardinality intermediate aggregates, btw. I am not sure |
I found I can' t run it successfully in my local... #12438 |
alamb
commented
Sep 12, 2024
It is probably because there are 17M groups which each is holding multiple aggregates each with non trivial state 🤔 |
Yes... I found the state is much larger than the simple accumulators(e.g. |
Rachelint
commented
Sep 12, 2024
I create a subset of SELECT"WatchID", "ClientIP", COUNT(*) AS c, approx_median("ResponseStartTiming") tmed FROM hits GROUP BY"WatchID", "ClientIP"ORDER BY c DESCLIMIT10; |
Rachelint
commented
Sep 12, 2024
This is the number from my local test with a subset(15%) of |
alamb
commented
Sep 13, 2024
I just ran this with some new queries on #12438 and this branch goes about 2x faster
./datafusion-cli-intermediate-state -f tq1.sql
DataFusion CLI v41.0.0
0 row(s) fetched.
Elapsed 0.019 seconds.
+-------------+---------------------+---+------+------+------+
| ClientIP | WatchID | c | tmin | tp95 | tmax |
+-------------+---------------------+---+------+------+------+
| 1611957945 | 6655575552203051303 | 2 | 0 | 0 | 0 || -1402644643 | 8566928176839891583 | 2 | 0 | 0 | 0 |
+-------------+---------------------+---+------+------+------+
2 row(s) fetched.
Elapsed 5.361 seconds.
+-------------+---------------------+---+------+------+------+
| ClientIP | WatchID | c | tmin | tmed | tmax |
+-------------+---------------------+---+------+------+------+
| 1611957945 | 6655575552203051303 | 2 | 0 | 0 | 0 || -1402644643 | 8566928176839891583 | 2 | 0 | 0 | 0 |
+-------------+---------------------+---+------+------+------+
2 row(s) fetched.
Elapsed 3.952 seconds.
andrewlamb@Andrews-MacBook-Pro-2 Downloads % datafusion-cli -f tq1.sql
datafusion-cli -f tq1.sql
DataFusion CLI v41.0.0
0 row(s) fetched.
Elapsed 0.020 seconds.
+-------------+---------------------+---+------+------+------+
| ClientIP | WatchID | c | tmin | tp95 | tmax |
+-------------+---------------------+---+------+------+------+
| 1611957945 | 6655575552203051303 | 2 | 0 | 0 | 0 || -1402644643 | 8566928176839891583 | 2 | 0 | 0 | 0 |
+-------------+---------------------+---+------+------+------+
2 row(s) fetched.
Elapsed 9.777 seconds.
+-------------+---------------------+---+------+------+------+
| ClientIP | WatchID | c | tmin | tmed | tmax |
+-------------+---------------------+---+------+------+------+
| 1611957945 | 6655575552203051303 | 2 | 0 | 0 | 0 || -1402644643 | 8566928176839891583 | 2 | 0 | 0 | 0 |
+-------------+---------------------+---+------+------+------+
2 row(s) fetched.
Elapsed 6.919 seconds. |
convert_to_state for GroupsAccumulatorAdapter.convert_to_state for GroupsAccumulatorAdapter (faster median for high cardinality aggregates)
alamb
left a comment
There was a problem hiding this comment.
Thank you @Rachelint and @korowa
While I think the real way to make MEDIAN and APPROX_PERCENTILE_CONT etc faster is to implement GroupsAccumulator, this PR makes them faster for certain cases.
Nice work. Thanks again and sorry for the delay in reviewing while we sorted out benchmarking
| let mut results = vec![]; | ||
| for row_idx in 0..num_rows { | ||
| // Create the empty accumulator for converting | ||
| let mut converted_accumulator = (self.factory)()?; |
There was a problem hiding this comment.
as a follow on PR I wonder if we could potentially to improve performance by adding a clear() or reset() type function to each accumulator to avoid having to create a new accumulator for each group.
There was a problem hiding this comment.
Yes, I want to reuse the converted_accumulator at the beginning, but it is not ensure that the state will be reset after calling state.
It is clever to add such function to do the reset work explicitly.
alamb
commented
Sep 15, 2024
The 42.0.0 release has been cut -- let's start the code flowing! |
alamb
commented
Sep 15, 2024
Thanks again @Rachelint |
Which issue does this PR close?
Closes#11819
Rationale for this change
See #11819
What changes are included in this PR?
Impl
convert_to_stateforGroupsAccumulatorAdapter.Are these changes tested?
Test by exists.
Are there any user-facing changes?
No.