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

github-merge-queue[bot] pushed a commit to branch 
gh-readonly-queue/main/pr-11313-a1daa4a10b0c207963dce0b0d98be7640c2d32ca
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git

commit c77ae6e3b846dffbf7f769845be19b2baeb5d488
Author: Kosta Tarasov <[email protected]>
AuthorDate: Mon Oct 5 18:19:46 2026 +0000

    Add focused integer-to-decimal cast benchmarks (#11313)
    
    # Which issue does this PR close?
    
    Part of #11309.
    
    # Rationale for this change
    
    The existing integer-to-decimal benchmarks cover Int64 to Decimal32 at
    scales 0 and -1 with full-range random input, which mostly overflows.
    They do not isolate successful conversion or several scaling paths
    affected by extracting shared conversion logic for Arrow and Variant in
    #11309.
    
    # What changes are included in this PR?
    
    Add eight benchmarks selected for distinct conversion paths:
    
    - No scaling and scale-up, each in safe and strict mode.
    - Decimal256 scale-down.
    - The all-zero shortcut for an extreme negative scale.
    - Scaling before narrowing to the destination integer.
    - Precision overflow in safe mode, processing the whole array.
    
    Fixtures contain 8192 rows with approximately 10% nulls. Fixture
    construction runs outside the timed loop.
    
    # Are these changes tested?
    
    Validation before removing the fixture assertions:
    
    - All eight benchmark smoke cases pass against upstream main.
    - `cargo fmt --all -- --check`.
    - `cargo clippy -p arrow --bench cast_kernels --features test_utils --
    -D warnings`.
    
    After removing the fixture assertions, `cargo +1.98.1 fmt --all --
    --check` and `git diff --check` pass. A fresh benchmark compile check
    was blocked by the local disk quota.
    
    # Are there any user-facing changes?
    
    No. Benchmark additions only.
    
    # AI usage
    
    Developed with assistance from OpenAI Codex for the benchmarks,
    validation, and PR description.
---
 arrow/benches/cast_kernels.rs | 86 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 85 insertions(+), 1 deletion(-)

diff --git a/arrow/benches/cast_kernels.rs b/arrow/benches/cast_kernels.rs
index 811a46cd58..1bda28b51a 100644
--- a/arrow/benches/cast_kernels.rs
+++ b/arrow/benches/cast_kernels.rs
@@ -26,7 +26,7 @@ use chrono::{DateTime, NaiveDate, NaiveDateTime};
 use std::sync::Arc;
 
 use arrow::array::*;
-use arrow::compute::cast;
+use arrow::compute::{CastOptions, cast, cast_with_options};
 use arrow::datatypes::*;
 use arrow::util::bench_util::*;
 use arrow::util::test_util::seedable_rng;
@@ -716,6 +716,90 @@ fn add_benchmark(c: &mut Criterion) {
         let target_type = DataType::Utf8;
         b.iter(|| cast(&timestamp_micro_utc_array, &target_type).unwrap());
     });
+
+    const ROWS: usize = 8192;
+    let mut bench = |name: &str, input: ArrayRef, target: DataType, modes: 
&[bool]| {
+        for &safe in modes {
+            let options = CastOptions {
+                safe,
+                ..Default::default()
+            };
+            let mode = if safe { "safe" } else { "strict" };
+            c.bench_function(&format!("{name} {mode}"), |b| {
+                b.iter(|| {
+                    cast_with_options(
+                        hint::black_box(input.as_ref()),
+                        hint::black_box(&target),
+                        &options,
+                    )
+                    .unwrap()
+                })
+            });
+        }
+    };
+
+    // Choose fixtures for distinct conversion paths, rather than every type 
pair.
+    let int32: ArrayRef = Arc::new(create_primitive_array_range::<Int32Type>(
+        ROWS,
+        0.1,
+        -1_000_000..1_000_000,
+    ));
+    let int64: ArrayRef = Arc::new(create_primitive_array_range::<Int64Type>(
+        ROWS,
+        0.1,
+        10..1_000_000,
+    ));
+    let uint64: ArrayRef = Arc::new(create_primitive_array_range::<UInt64Type>(
+        ROWS,
+        0.1,
+        10..1_000_000,
+    ));
+    for (name, input, target) in [
+        (
+            "cast int32 to decimal32(9, 0) 8192 valid",
+            int32,
+            DataType::Decimal32(9, 0),
+        ),
+        (
+            "cast int64 to decimal128(38, 2) 8192 valid",
+            int64.clone(),
+            DataType::Decimal128(38, 2),
+        ),
+    ] {
+        bench(name, input, target, &[true, false]);
+    }
+    bench(
+        "cast uint64 to decimal256(76, -1) 8192 scale down",
+        uint64,
+        DataType::Decimal256(76, -1),
+        &[true],
+    );
+    bench(
+        "cast int64 to decimal32(9, -20) 8192 all zero",
+        int64,
+        DataType::Decimal32(9, -20),
+        &[true],
+    );
+    let overflow: ArrayRef = 
Arc::new(create_primitive_array_range::<Int32Type>(
+        ROWS,
+        0.1,
+        100_000_000..1_000_000_000,
+    ));
+    bench(
+        "cast int32 to decimal32(8, 0) 8192 precision overflow",
+        overflow,
+        DataType::Decimal32(8, 0),
+        &[true],
+    );
+    let wide: ArrayRef = Arc::new(Int64Array::from_iter(
+        (0..ROWS).map(|i| (i % 10 != 0).then_some(5_000_000_000 + i as i64)),
+    ));
+    bench(
+        "cast int64 to decimal32(9, -1) 8192 scale before narrowing",
+        wide,
+        DataType::Decimal32(9, -1),
+        &[true],
+    );
 }
 
 criterion_group!(benches, add_benchmark);

Reply via email to