This is an automated email from the ASF dual-hosted git repository.
Jefffrey pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/main by this push:
new 20bd84898d perf: Optimize display of Boolean values (#11254)
20bd84898d is described below
commit 20bd84898ddd519ba68319e90efcfb95df23c973
Author: Neil Conway <[email protected]>
AuthorDate: Tue Sep 29 04:33:56 2026 -0400
perf: Optimize display of Boolean values (#11254)
# Which issue does this PR close?
- N/A
# Rationale for this change
We previously went through `write!` when displaying Boolean values,
which goes through the general-purpose formatting machinery. It is a
one-liner to special-case Boolean values instead. This speeds up CSV
output and pretty printing.
Benchmark: (M4 Max)
* `format_boolean/random`: 96.0 µs -> 77.6 µs, −19.8%
# What changes are included in this PR?
* Optimize display for Boolean values
* Add benchmark
# Are these changes tested?
Yes, covered by existing tests.
# Are there any user-facing changes?
No.
# AI usage
Developed with Claude Code (Opus 5.5). I have reviewed and understand
the resulting code.
---
arrow-cast/Cargo.toml | 4 +++
arrow-cast/benches/format_boolean.rs | 48 ++++++++++++++++++++++++++++++++++++
arrow-cast/src/display.rs | 2 +-
3 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/arrow-cast/Cargo.toml b/arrow-cast/Cargo.toml
index 9e4a43a8d9..4880958195 100644
--- a/arrow-cast/Cargo.toml
+++ b/arrow-cast/Cargo.toml
@@ -91,3 +91,7 @@ workspace = true
[[bench]]
name = "format_decimal"
harness = false
+
+[[bench]]
+name = "format_boolean"
+harness = false
diff --git a/arrow-cast/benches/format_boolean.rs
b/arrow-cast/benches/format_boolean.rs
new file mode 100644
index 0000000000..61c0da7dde
--- /dev/null
+++ b/arrow-cast/benches/format_boolean.rs
@@ -0,0 +1,48 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+use std::hint::black_box;
+
+use arrow_array::BooleanArray;
+use arrow_cast::display::{ArrayFormatter, FormatOptions};
+use criterion::{Criterion, Throughput, criterion_group, criterion_main};
+use rand::rngs::StdRng;
+use rand::{RngExt, SeedableRng};
+
+const ARRAY_LEN: usize = 8192;
+
+fn format_array(c: &mut Criterion) {
+ let mut rng = StdRng::seed_from_u64(42);
+ let array = BooleanArray::from((0..ARRAY_LEN).map(|_|
rng.random()).collect::<Vec<bool>>());
+ let formatter = ArrayFormatter::try_new(&array,
&FormatOptions::new()).unwrap();
+ let mut output = String::with_capacity(8);
+
+ let mut group = c.benchmark_group("format_boolean");
+ group.throughput(Throughput::Elements(ARRAY_LEN as u64));
+ group.bench_function("random", |b| {
+ b.iter(|| {
+ for idx in 0..array.len() {
+ output.clear();
+ formatter.value(idx).write(&mut output).unwrap();
+ }
+ black_box(&output);
+ })
+ });
+ group.finish();
+}
+
+criterion_group!(benches, format_array);
+criterion_main!(benches);
diff --git a/arrow-cast/src/display.rs b/arrow-cast/src/display.rs
index e27421f8c4..55f7d2661a 100644
--- a/arrow-cast/src/display.rs
+++ b/arrow-cast/src/display.rs
@@ -674,7 +674,7 @@ impl<'a, F: DisplayIndexState<'a> + Array> DisplayIndex for
ArrayFormat<'a, F> {
impl DisplayIndex for &BooleanArray {
fn write(&self, idx: usize, f: &mut dyn Write) -> FormatResult {
- write!(f, "{}", self.value(idx))?;
+ f.write_str(if self.value(idx) { "true" } else { "false" })?;
Ok(())
}
}