alamb commented on code in PR #10054:
URL: 
https://github.com/apache/arrow-datafusion/pull/10054#discussion_r1564780071


##########
datafusion/functions/src/string/overlay.rs:
##########
@@ -88,10 +105,13 @@ pub fn overlay<T: OffsetSizeTrait>(args: &[ArrayRef]) -> 
Result<ArrayRef> {
             let characters_array = as_generic_string_array::<T>(&args[1])?;
             let pos_num = as_int64_array(&args[2])?;
 
+            let characters_array_iter = 
adaptive_array_iter(characters_array.iter());

Review Comment:
   > According to the benchmark, there can be about a 12% performance 
improvement 🚀 when there are 3 scalar args; however, when all args are arrays, 
there is a 2% ~ 3% performance loss 😔. Does anyone have any ideas on how to 
avoid this loss?
   
   One reason it may be getting slower is that there is overhead now during 
iteration (where it has to switch on `Left/Right` in each element
   
   One thing to try would be to avoid the `Left/Right` iterator by 
instantiating different loops depending on the input types
   
   So something like 
   
   ```rust
   
   fn<CI, PI> overlay3(string_array: &StringArray, characters_array_iter: CI, 
pos_num_iter: PI) -> Result<ArrayRef> 
   where
     CI: Iterator<Item = char>,
     PI: Iterator<Item =usize>
   {
       let result = string_array
                   .iter()
                   .zip(characters_array_iter)
                   .zip(pos_num_iter)
                   .map(|((string, characters), start_pos)| {
   ...
   }
   ```
   And then you need to instantiate versions based on lengths:
   
   ```rust
   match (character_array.len(), pos_num.len()) { 
     (1, 1) => {
           let c_value = character_array.next().expect("Contains a value");
           let p_value = pos_num.next().expect("Contains a value");
           overlay3(character_array, std::iter::repeat(c_value, len), 
std;:iter::repeat(p_value, len))
     (1, _) => {
           let c_value = character_array.next().expect("Contains a value");
           overlay3(character_array, std::iter::repeat(c_value, len), 
pos_num.iter())
     ...
   }
   ```
     



##########
datafusion/functions/src/string/overlay.rs:
##########
@@ -88,10 +105,13 @@ pub fn overlay<T: OffsetSizeTrait>(args: &[ArrayRef]) -> 
Result<ArrayRef> {
             let characters_array = as_generic_string_array::<T>(&args[1])?;
             let pos_num = as_int64_array(&args[2])?;
 
+            let characters_array_iter = 
adaptive_array_iter(characters_array.iter());
+            let pos_num_iter = adaptive_array_iter(pos_num.iter());
+
             let result = string_array
                 .iter()
-                .zip(characters_array.iter())
-                .zip(pos_num.iter())
+                .zip(characters_array_iter)
+                .zip(pos_num_iter)

Review Comment:
   While looking at the innter loop of this function, you can probably get a 
major boost by avoiding `String::with_capacoty` and instead reuse the same 
`String` on each element. It might also be possible to skip the copy by using 
StringBuilder directly rather than copying to a temp string



-- 
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]

Reply via email to