This is an automated email from the ASF dual-hosted git repository.
alamb 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 27f68b1659 docs: update primitive docs to focus on vec<T> (#10898)
27f68b1659 is described below
commit 27f68b1659e40d7aaccfbfcb52b7cc035ef8a042
Author: RIchard Baah <[email protected]>
AuthorDate: Fri Aug 28 05:21:15 2026 -0400
docs: update primitive docs to focus on vec<T> (#10898)
# Which issue does this PR close?
<!--
We generally require a GitHub issue to be filed for all bug fixes and
enhancements and this helps us generate change logs for our releases.
You can link an issue to this PR using the GitHub syntax.
-->
- Closes #7297.
- follow up to https://github.com/apache/arrow-rs/pull/10895
# Rationale for this change
see #7297
<!--
Why are you proposing this change? If this is already explained clearly
in the issue then this section is not needed.
Explaining clearly why changes are proposed helps reviewers understand
your changes and offer better suggestions for fixes.
-->
# What changes are included in this PR?
adds doc comment on `PrimitiveBuilder<T>` and `PrimitiveArray<T>`
explaining when to use `Primtive:from(vec![T,T,T...])` vs
`PrimitiveBuilder::new()`
<!--
There is no need to duplicate the description in the issue here but it
is sometimes worth providing a summary of the individual changes in this
PR.
-->
# Are these changes tested?
n/a
<!--
We typically require tests for all PRs in order to:
1. Prevent the code from being accidentally broken by subsequent changes
2. Serve as another way to document the expected behavior of the code
If tests are not included in your PR, please explain why (for example,
are they covered by existing tests)?
If this PR claims a performance improvement, please include evidence
such as benchmark results.
-->
# Are there any user-facing changes?
n/a
<!--
If there are user-facing changes then we may require documentation to be
updated before approving the PR.
If there are any breaking changes to public APIs, please call them out.
-->
---
arrow-array/src/array/primitive_array.rs | 16 ++++++------
arrow-array/src/builder/primitive_builder.rs | 37 ++++++++++++++++++----------
2 files changed, 31 insertions(+), 22 deletions(-)
diff --git a/arrow-array/src/array/primitive_array.rs
b/arrow-array/src/array/primitive_array.rs
index 5058dbc9ac..09ab889f73 100644
--- a/arrow-array/src/array/primitive_array.rs
+++ b/arrow-array/src/array/primitive_array.rs
@@ -583,15 +583,13 @@ pub use crate::types::ArrowPrimitiveType;
///
/// # Performance: Choosing Between `from` and [`PrimitiveBuilder`]
///
-/// When all values are known upfront, constructing a `PrimitiveArray`
directly via
-/// [`PrimitiveArray::from`] or [`PrimitiveArray::new`] is significantly
faster than
-/// using [`PrimitiveBuilder`]:
-///
-/// - **`PrimitiveArray::from(vec![...])`** — zero-copy from `Vec`; no
per-element
-/// bookkeeping. Prefer this whenever values are already collected.
-/// - **[`PrimitiveBuilder`]** — allocates incrementally and tracks nullability
-/// per-element. Use this only when values must be appended one-at-a-time
inside a
-/// loop where the final size is not known in advance.
+/// Rust's `Vec` is highly optimized, and Arrow's conversion from `Vec` to
+/// `PrimitiveArray` is zero-copy. Prefer [`PrimitiveArray::from`] or
+/// [`PrimitiveArray::new`] whenever values are already in a `Vec` or can be
collected
+/// into one. [`PrimitiveBuilder`] is backed by a `Vec` and a
`NullBufferBuilder`
+/// internally, so it offers no performance advantage. Use it when the array
may
+/// contain nulls whose positions aren't known upfront, since it keeps values
and the
+/// null bitmask in sync automatically.
///
/// # Example: Get a `PrimitiveArray` from an [`ArrayRef`]
/// ```
diff --git a/arrow-array/src/builder/primitive_builder.rs
b/arrow-array/src/builder/primitive_builder.rs
index e3610e4ea7..85c345a5c6 100644
--- a/arrow-array/src/builder/primitive_builder.rs
+++ b/arrow-array/src/builder/primitive_builder.rs
@@ -99,33 +99,44 @@ pub type Decimal256Builder =
PrimitiveBuilder<Decimal256Type>;
///
/// # Performance
///
-/// When all values are known upfront, prefer constructing a
[`PrimitiveArray`] directly
-/// via [`PrimitiveArray::from`] or [`PrimitiveArray::new`] instead of using
this builder.
-/// Direct construction reuses the existing allocation (zero-copy from `Vec`)
and avoids
-/// the overhead of per-element bookkeeping, making it significantly faster.
-///
-/// Use [`PrimitiveBuilder`] when values must be appended **incrementally** —
for example,
-/// inside a loop where the final size is not known in advance.
-///
-/// # Example
+/// Rust's `Vec` is highly optimized, and Arrow's conversion from `Vec` to
+/// [`PrimitiveArray`] is zero-copy — the array reuses the same underlying
allocation
+/// without any data being copied. If your values are already in a `Vec`, or
can be
+/// collected into one, prefer constructing a [`PrimitiveArray`] directly:
///
/// ```
/// # use arrow_array::{Int32Array, Array};
-/// // Prefer this when values are known upfront (zero-copy, no per-element
overhead):
+/// // Zero-copy: the array reuses the Vec's allocation
/// let array = Int32Array::from(vec![1, 2, 3]);
/// assert_eq!(array.len(), 3);
/// ```
///
+/// Internally, [`PrimitiveBuilder`] is itself backed by a `Vec<T::Native>`
and a
+/// [`NullBufferBuilder`], so using one does not unlock any additional
performance —
+/// it is simply a convenience wrapper for incremental construction.
+///
+/// # When to use [`PrimitiveBuilder`]
+///
+/// Prefer the builder when your array **may contain nulls but you don't know
their
+/// positions upfront**. Managing a `Vec<T>` and a [`NullBufferBuilder`] in
parallel
+/// by hand is error-prone; the builder keeps them in sync automatically as
you call
+/// [`append_value`](PrimitiveBuilder::append_value) and
+/// [`append_null`](PrimitiveBuilder::append_null).
+///
/// ```
/// # use arrow_array::builder::Int32Builder;
/// # use arrow_array::Array;
-/// // Use the builder when appending values one-by-one:
/// let mut builder = Int32Builder::new();
-/// for v in [1, 2, 3] {
-/// builder.append_value(v);
+/// for (i, v) in [1, 2, 3].iter().enumerate() {
+/// if i == 1 {
+/// builder.append_null();
+/// } else {
+/// builder.append_value(*v);
+/// }
/// }
/// let array = builder.finish();
/// assert_eq!(array.len(), 3);
+/// assert!(array.is_null(1));
/// ```
#[derive(Debug)]
pub struct PrimitiveBuilder<T: ArrowPrimitiveType> {