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(×tamp_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);
