Rich-T-kid commented on issue #7001:
URL: https://github.com/apache/datafusion/issues/7001#issuecomment-5801503499

   Okay I think I have a few ideas for how we can speed up RepartionExec. first 
lets do a review so everyone is on the same page.
   
   <img width="2928" height="1362" alt="Image" 
src="https://github.com/user-attachments/assets/a0807852-4857-469d-8240-c39bc24c0b8e";
 />
   
   At a high level this is how repartionExec, specifically the HashRepartion 
path.
   
   1. hash the key columns. `M`,`N`,`K` in `Hash(M,N,K)` 
   2.  Call `take_arrays()` once per input batch to produce one reordered 
batch, then slice() it into per-partition sub-batches 
(https://github.com/apache/datafusion/pull/22159)
   3.  Each sub-batch is pushed into its output partition's `SharedCoalescer`, 
which buffers rows behind a Mutex until `target_batch_size` is reached
   4.  When `target_batch_size` is reached, `push_and_drain()` returns the 
completed batch, which is then sent over the partition's async channel to the 
consumer side
   
   
   The most CPU-intensive parts of this are `take_arrays()` and `push_batch()`, 
since every row passes through both. Key hashing only scales with the number of 
columns being hashed, and as @gabotechs found 
[here](https://github.com/apache/datafusion/pull/23720#issuecomment-5104141874),
 improvements there would only be marginal.
   
   
   I've been working on a [series of take 
optimizations](https://github.com/apache/arrow-rs/issues/8879) in arrow-rs that 
build on top of one another nicely — [optimize take bool & take 
utf8View](https://github.com/apache/arrow-rs/pull/10813), [optimize take 
list](https://github.com/apache/arrow-rs/pull/10812), [optimize 
fsl](https://github.com/apache/arrow-rs/pull/10441), etc. The most important 
piece is the final one, 
[#10945](https://github.com/apache/arrow-rs/pull/10945), which has shown up to 
a 25% speedup.
   
   Simply swapping the existing methods for the new ones introduced in that PR 
should yield significant improvements here, given how heavily RepartitionExec 
relies on take.
   
   That leaves SharedCoalescer, which is a thin wrapper around 
[BatchCoalescer](https://arrow.apache.org/rust/arrow/compute/struct.BatchCoalescer).
 I've made a few attempts to 
[optimize](https://github.com/apache/arrow-rs/issues/7761) this, with little to 
no success, but I think the best return on effort is [Optimize 
BatchCoalescer::push_batch_with_indices](https://github.com/apache/arrow-rs/issues/8957)
 (by @Dandandan).
   
   The core issue is that we're constrained by having to copy repeatedly. 
`take()` has to copy every byte from input to output, and BatchCoalescer 
(except for primitives, utf8View, and fixed-size binary) has to allocate 2x 
memory and then copy the bytes from source to destination. Right now this copy 
happens twice; simply reducing that to a single copy could be a significant win.
   
   <img width="2828" height="1396" alt="Image" 
src="https://github.com/user-attachments/assets/e5fa6c96-88bb-4afb-8e92-c3fca814cfff";
 />
   
   What Im proposing is to avoid the `take_arrays()` call in place for passing 
a zero-copy slice to `SharedCoalescer` as well as the indices that would have 
went to `take_arrays()`. then SharedCoacler would use 
`push_batch_with_indices()`. the issue with using this today is that this 
method is just a wrapper for `take_arrays()` 
https://github.com/apache/arrow-rs/blob/e491ce6c6f343ff9d7a235376d0353d12b365330/arrow-select/src/coalesce.rs#L291.
   
   The first step towards this is updating the backing trait `InprogressArrays` 
to take advantage of `push_batch_with_indices()` by writing the intermediate 
state directly to the output buffer. That is introduced in this PR 
https://github.com/apache/arrow-rs/pull/11174.
   
   
   Besides that I think the other largest wins are trying to speed up the 
concat kernel as this is the generic path (non-primitves/View types).
   
   
   
   
   
   
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to