Skip to content

Conversation

@binmahone
Copy link
Collaborator

@binmahone binmahone commented Dec 22, 2025

  • Skip isNotNull + ifElse when lhs.getNullCount == 0
  • Directly return lhs.incRefCount() for better performance

This PR is broke up from #14032, please visit that to see more details

- Skip isNotNull + ifElse when lhs.getNullCount == 0
- Directly return lhs.incRefCount() for better performance

Signed-off-by: Hongbin Ma (Mahone) <mahongbin@apache.org>
Copilot AI review requested due to automatic review settings December 22, 2025 14:17
@binmahone
Copy link
Collaborator Author

build

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Dec 22, 2025

Greptile Summary

Optimization that adds a fast path to GpuNvl when the left-hand side column has no null values. Instead of computing isNotNull and performing conditional logic with ifElse, the code now checks if lhs.getNullCount == 0 and directly returns lhs.incRefCount(), skipping unnecessary operations.

Key changes:

  • Both apply(lhs: ColumnVector, rhs: ColumnVector) and apply(lhs: ColumnVector, rhs: Scalar) overloads now include the fast path check
  • When lhs.getNullCount == 0, returns lhs with incremented reference count immediately
  • When nulls exist, falls back to original logic using isNotNull + ifElse
  • Follows existing optimization patterns in the codebase (similar to GpuCast.scala:1417)
  • Memory management is correct with proper reference counting

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The optimization is straightforward, follows existing patterns in the codebase, correctly handles memory management with incRefCount(), and preserves the original behavior when nulls are present. The fast path check is efficient and the logic is sound.
  • No files require special attention

Important Files Changed

Filename Overview
sql-plugin/src/main/scala/com/nvidia/spark/rapids/nullExpressions.scala Added fast path optimization for GpuNvl when left-hand side has no nulls, directly returning reference-counted lhs instead of performing null check and conditional logic

Sequence Diagram

sequenceDiagram
    participant Caller
    participant GpuNvl
    participant ColumnVector as lhs ColumnVector
    participant RHS as rhs (ColumnVector/Scalar)
    
    Caller->>GpuNvl: apply(lhs, rhs)
    GpuNvl->>ColumnVector: getNullCount()
    
    alt lhs has no nulls (nullCount == 0)
        Note over GpuNvl: Fast path optimization
        GpuNvl->>ColumnVector: incRefCount()
        ColumnVector-->>GpuNvl: return lhs with incremented ref
        GpuNvl-->>Caller: return lhs
    else lhs has nulls (nullCount > 0)
        Note over GpuNvl: Original path
        GpuNvl->>ColumnVector: isNotNull()
        ColumnVector-->>GpuNvl: boolean mask
        GpuNvl->>GpuNvl: ifElse(lhs, rhs) using mask
        Note over GpuNvl: withResource closes mask
        GpuNvl-->>Caller: return result
    end
Loading

@binmahone binmahone requested a review from abellina December 22, 2025 14:20
@binmahone binmahone self-assigned this Dec 22, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a performance optimization to the GpuNvl object by introducing a fast path when the left-hand side column has no null values. Instead of performing the isNotNull check and ifElse operation, it directly returns the lhs column with an incremented reference count.

  • Added fast path optimization that skips unnecessary null checks when lhs.getNullCount == 0
  • Applied the same optimization to both overloaded apply methods (ColumnVector and Scalar variants)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +32 to +35
// Fast path: if lhs has no nulls, just return lhs directly
if (lhs.getNullCount == 0) {
lhs.incRefCount()
} else {
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fast path optimization when lhs has no nulls should have explicit test coverage. Consider adding a test case in conditionals_test.py that exercises the scenario where the first argument to nvl() has nullable=False, to ensure this optimization path is tested. For example, you could add a test like test_nvl with binary_op_df using a data_gen with nullable=False.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

@revans2 revans2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks good, but I don't see any performance numbers. Might be worth filing a follow on issue to look at all other null related expressions. In the past null count was something that was calculated lazily, but then CUDF changed it and we never went back and optimized things knowing that it is not cheap to use.

if (lhs.getNullCount == 0) {
lhs.incRefCount()
} else {
withResource(lhs.isNotNull) { isLhsNotNull =>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: If we are doing this level of optimization, would it be worth testing to see the performance improvement for using the following APIs instead.

https://github.com/rapidsai/cudf/blob/1d20c668b932cdb864389427fdaef972a5168d03/java/src/main/java/ai/rapids/cudf/ColumnView.java#L536-L548

Copy link
Collaborator

@abellina abellina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same questions as @revans2. Do note we need to update copyright.

@sameerz sameerz added the performance A performance related task/issue label Jan 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance A performance related task/issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants