comphead commented on code in PR #26533:
URL: https://github.com/apache/datafusion/pull/26533#discussion_r4329757771


##########
datafusion/functions-window/src/nth_value.rs:
##########
@@ -525,27 +527,26 @@ impl NthValueEvaluator {
         }
     }
 
-    fn valid_index_with_nulls(&self, nulls: &NullBuffer, offset: usize) -> 
Option<usize> {
+    /// Returns the index within the frame of the value to return, given the 
frame's validity
+    /// bits.
+    fn valid_index_with_nulls(&self, valid: &BooleanBuffer) -> Option<usize> {
         match self.state.kind {
-            NthValueKind::First => nulls.valid_indices().next().map(|idx| idx 
+ offset),
-            NthValueKind::Last => nulls.valid_indices().last().map(|idx| idx + 
offset),
+            NthValueKind::First => valid.set_indices().next(),
+            NthValueKind::Last => last_set_bit(valid),
             NthValueKind::Nth => {
                 match self.n.cmp(&0) {
                     Ordering::Greater => {
                         // SQL indices are not 0-based.
                         let index = (self.n as usize) - 1;
-                        nulls.valid_indices().nth(index).map(|idx| idx + 
offset)
+                        valid.set_indices().nth(index)
                     }
                     Ordering::Less => {
                         let reverse_index = (-self.n) as usize;
-                        let valid_indices_len = nulls.len() - 
nulls.null_count();
+                        let valid_indices_len = valid.count_set_bits();
                         if reverse_index > valid_indices_len {
                             return None;
                         }
-                        nulls
-                            .valid_indices()
-                            .nth(valid_indices_len - reverse_index)
-                            .map(|idx| idx + offset)
+                        valid.set_indices().nth(valid_indices_len - 
reverse_index)

Review Comment:
   Thanks @andygrove, good catch. I took your `nth_set_bit_from_end` as written 
in 70fa4d9d5. It now covers both `LAST_VALUE` and `NTH_VALUE(expr, -n)`, and 
the unit test checks `n` in `[1, 2, 3, 63, 64, 65, 130]`. I kept a single 
helper. The extra popcount costs `LAST_VALUE` about 1 ns per row here too.
   
   `nth_value` bench on an Apple M5 Max, the previous head against this commit:
   
   | Benchmark | a717eb436 | 70fa4d9d5 |
   |---|---:|---:|
   | `nth_value_neg10_expanding/30%_nulls` | 13.40 ms | 147 µs |
   | `nth_value_neg10_expanding/50%_nulls` | 7.64 ms | 156 µs |
   | `nth_value_neg10_expanding/80%_nulls` | 2.41 ms | 156 µs |
   | `last_value_expanding/50%_nulls` | 113 µs | 120 µs |
   | `last_value_sliding_100/50%_nulls` | 116 µs | 126 µs |
   
   `window.slt` and the extended test suite pass. I filed #26537 for the 
`memoize` early return and updated the description.
   



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