This is an automated email from the ASF dual-hosted git repository.

Mryange pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new aa95d10dc7d [opt](expr) Improve scalar function auto-vectorization 
(#65908)
aa95d10dc7d is described below

commit aa95d10dc7df6262c829a0d6980a81d74b83a539
Author: Mryange <[email protected]>
AuthorDate: Wed Jul 29 11:13:37 2026 +0800

    [opt](expr) Improve scalar function auto-vectorization (#65908)
    
    ### What problem does this PR solve?
    
    Issue Number: N/A
    
    Problem Summary:
    
    Several scalar-function hot loops repeatedly extracted constant-column
    values, performed branchy
    null-map writes, or accessed `PODArray` through wrapper methods on every
    row. These loop shapes
    prevented Clang from generating efficient vector code.
    
    This change hoists invariant bit and bit-shift operands out of the
    loops, writes nullable math
    predicates unconditionally, and obtains raw input and output pointers
    before the `width_bucket`
    loop. Focused benchmarks showed approximately 92%-98% lower CPU time for
    constant bit operations,
    28%-94% lower CPU time for nullable math null-map generation, and 3%-9%
    lower CPU time for Float32
    `width_bucket`.
    
    ### Release note
    
    None
    
    ### Check List (For Author)
    
    - Test <!-- At least one of them must be included. -->
        - [ ] Regression test
        - [ ] Unit Test
        - [ ] Manual test (add detailed scripts or steps below)
        - [ ] No need to test or manual test. Explain why:
    - [ ] This is a refactor/code format and no logic has been changed.
            - [ ] Previous test can cover this change.
            - [ ] No code files have been changed.
            - [ ] Other reason <!-- Add your reason?  -->
    
    - Behavior changed:
        - [ ] No.
        - [ ] Yes. <!-- Explain the behavior change -->
    
    - Does this need documentation?
        - [ ] No.
    - [ ] Yes. <!-- Add document PR link here. eg:
    https://github.com/apache/doris-website/pull/1214 -->
    
    ### Check List (For Reviewer who merge this PR)
    
    - [ ] Confirm the release note
    - [ ] Confirm test cases
    - [ ] Confirm document
    - [ ] Add branch pick label <!-- Add branch pick label that this PR
    should merge into -->
---
 be/src/exprs/function/function_bit.cpp               |  6 ++++--
 be/src/exprs/function/function_bit_shift.cpp         |  6 ++++--
 .../function/function_math_unary_alway_nullable.h    |  8 ++++----
 be/src/exprs/function/function_width_bucket.cpp      | 20 +++++++++++---------
 4 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/be/src/exprs/function/function_bit.cpp 
b/be/src/exprs/function/function_bit.cpp
index 2cf72dbe530..9b0ab7c229e 100644
--- a/be/src/exprs/function/function_bit.cpp
+++ b/be/src/exprs/function/function_bit.cpp
@@ -100,8 +100,9 @@ private:
         auto& a = column_left_ptr->get_data();
         auto& c = column_result->get_data();
         size_t size = a.size();
+        const auto right_value = column_right_ptr->template 
get_value<Impl::ArgPType>();
         for (size_t i = 0; i < size; ++i) {
-            c[i] = Impl::apply(a[i], column_right_ptr->template 
get_value<Impl::ArgPType>());
+            c[i] = Impl::apply(a[i], right_value);
         }
         return column_result;
     }
@@ -116,8 +117,9 @@ private:
         auto& b = column_right_ptr->get_data();
         auto& c = column_result->get_data();
         size_t size = b.size();
+        const auto left_value = column_left_ptr->template 
get_value<Impl::ArgPType>();
         for (size_t i = 0; i < size; ++i) {
-            c[i] = Impl::apply(column_left_ptr->template 
get_value<Impl::ArgPType>(), b[i]);
+            c[i] = Impl::apply(left_value, b[i]);
         }
         return column_result;
     }
diff --git a/be/src/exprs/function/function_bit_shift.cpp 
b/be/src/exprs/function/function_bit_shift.cpp
index ec275146098..9e90992daa6 100644
--- a/be/src/exprs/function/function_bit_shift.cpp
+++ b/be/src/exprs/function/function_bit_shift.cpp
@@ -88,8 +88,9 @@ private:
         auto& a = column_left_ptr->get_data();
         auto& c = column_result->get_data();
         size_t size = a.size();
+        const auto right_value = column_right_ptr->template 
get_value<TYPE_TINYINT>();
         for (size_t i = 0; i < size; ++i) {
-            c[i] = Impl::apply(a[i], column_right_ptr->template 
get_value<TYPE_TINYINT>());
+            c[i] = Impl::apply(a[i], right_value);
         }
         return column_result;
     }
@@ -102,8 +103,9 @@ private:
         auto& b = column_right_ptr->get_data();
         auto& c = column_result->get_data();
         size_t size = b.size();
+        const auto left_value = column_left_ptr->template 
get_value<TYPE_BIGINT>();
         for (size_t i = 0; i < size; ++i) {
-            c[i] = Impl::apply(column_left_ptr->template 
get_value<TYPE_BIGINT>(), b[i]);
+            c[i] = Impl::apply(left_value, b[i]);
         }
         return column_result;
     }
diff --git a/be/src/exprs/function/function_math_unary_alway_nullable.h 
b/be/src/exprs/function/function_math_unary_alway_nullable.h
index 174ea6a5e54..879a17c3edd 100644
--- a/be/src/exprs/function/function_math_unary_alway_nullable.h
+++ b/be/src/exprs/function/function_math_unary_alway_nullable.h
@@ -61,14 +61,14 @@ private:
         auto& dst_data = dst->get_data();
         dst_data.resize(input_rows_count);
 
-        execute_in_iterations(col->get_data().data(), dst_data.data(), 
input_rows_count);
+        const auto* input_data = col->get_data().data();
+        execute_in_iterations(input_data, dst_data.data(), input_rows_count);
 
         auto result_null_map = ColumnUInt8::create(input_rows_count, 0);
+        auto* result_null_map_data = result_null_map->get_data().data();
 
         for (size_t i = 0; i < input_rows_count; i++) {
-            if (Impl::is_invalid_input(col->get_data()[i])) [[unlikely]] {
-                result_null_map->get_data().data()[i] = 1;
-            }
+            result_null_map_data[i] = Impl::is_invalid_input(input_data[i]);
         }
 
         block.replace_by_position(
diff --git a/be/src/exprs/function/function_width_bucket.cpp 
b/be/src/exprs/function/function_width_bucket.cpp
index 5546dd051d2..f9660551b99 100644
--- a/be/src/exprs/function/function_width_bucket.cpp
+++ b/be/src/exprs/function/function_width_bucket.cpp
@@ -101,22 +101,24 @@ private:
         auto& nested_column_concrete = *nested_column;
 
         size_t input_rows_count = expr_column.size();
+        const auto* expr_data = expr_column_concrete.get_data().data();
+        const auto* min_value_data = 
min_value_column_concrete.get_data().data();
+        const auto* max_value_data = 
max_value_column_concrete.get_data().data();
+        auto* nested_data = nested_column_concrete.get_data().data();
 
         for (size_t i = 0; i < input_rows_count; ++i) {
-            auto min_value = min_value_column_concrete.get_data()[i];
-            auto max_value = max_value_column_concrete.get_data()[i];
+            auto min_value = min_value_data[i];
+            auto max_value = max_value_data[i];
             auto average_value = (max_value - min_value) / (1.0 * num_buckets);
-            if (expr_column_concrete.get_data()[i] < min_value) {
+            if (expr_data[i] < min_value) {
                 continue;
-            } else if (expr_column_concrete.get_data()[i] >= max_value) {
-                nested_column_concrete.get_data()[i] = num_buckets + 1;
+            } else if (expr_data[i] >= max_value) {
+                nested_data[i] = num_buckets + 1;
             } else {
                 if ((max_value - min_value) / num_buckets == 0) {
                     continue;
                 }
-                nested_column_concrete.get_data()[i] =
-                        (int64_t)(1 +
-                                  (expr_column_concrete.get_data()[i] - 
min_value) / average_value);
+                nested_data[i] = (int64_t)(1 + (expr_data[i] - min_value) / 
average_value);
             }
         }
     }
@@ -162,4 +164,4 @@ void register_function_width_bucket(SimpleFunctionFactory& 
factory) {
     factory.register_function<FunctionWidthBucket>();
 }
 
-} // namespace doris
\ No newline at end of file
+} // namespace doris


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

Reply via email to