andygrove commented on PR #5403:
URL: 
https://github.com/apache/datafusion-comet/pull/5403#issuecomment-5441424463

   > **Note on this review:** this was generated by an LLM (Claude Code) at my 
request while I worked through a review backlog. I have not verified the 
individual findings myself. Please treat everything below as suggestions to 
evaluate rather than as authoritative review feedback, and push back on 
anything that is wrong or already handled.
   
   This is a good piece of work. Fixing native evaluation rather than routing 
through the codegen dispatcher is the right call, and the recursive 
`spark_comparator` with nulls-first ordering, dictionary decoding, and struct 
lexicographic comparison looks careful. I particularly appreciate that the 
description reports the slowdown honestly instead of burying it, and that the 
tests compare raw bits rather than numeric equality.
   
   The float slowdown is the thing I want to talk about.
   
   **1.5x to 1.6x on plain float arrays**
   
   `float_extrema` gives up Arrow's vectorized min/max and does a scalar loop 
with a per-element null check and two branches. That is a real cost paid by 
every user on every `array_min` and `array_max` over a float column, in order 
to fix a case that only arises when the array contains both zero signs or 
multiple NaN encodings.
   
   There is a fast path available here. Arrow's kernel and Spark disagree only 
when the winning value is a zero or a NaN. For any other winner, all tied 
candidates are bit-identical, so "keep the first" and "keep whichever Arrow 
found" produce the same bytes. So you could run Arrow's kernel first, and only 
when the result is `0.0`, `-0.0`, or NaN fall back to the scalar 
first-occurrence scan for that one list. Arrays with no zeros and no NaNs, 
which is essentially all real data, would then run at DataFusion's speed.
   
   Would that work? If there is a reason it does not, it would be good to say 
so in the code, because a permanent 1.6x on the common path to fix an edge case 
is a hard trade to justify otherwise.
   
   **`FixedSizeList` input reaches an `exec_err`**
   
   `needs_spark_ordering` returns true for `FixedSizeList` as an element type, 
and `spark_comparator` handles it. But `invoke_with_args` matches only 
`DataType::List` and `DataType::LargeList` on the outer array and returns 
`exec_err!("{} does not support type {other}")` for anything else. So 
`array_max` over a `FixedSizeList` column would now fail at runtime rather than 
falling back.
   
   I could not find a path where Comet produces a `FixedSizeList` here, so this 
may well be unreachable. If it is, could the match arm say so, along the lines 
of "Comet only produces List and LargeList; FixedSizeList is unreachable"? And 
if it is reachable, this needs either handling or a plan-time `Unsupported`.
   
   **Two smaller things**
   
   `spark_comparator`'s `Dictionary` arm calls `cast(array, value_type)`, which 
materializes the whole decoded values array on every invocation. For a heavily 
dictionary-encoded column that is a full decode per batch. Is that acceptable, 
or worth a note that dictionary elements are the slow path?
   
   The `Cargo.toml` change adds a trailing newline to an unrelated line. Not a 
problem, just noting it so it does not look accidental in the diff.
   


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