diff --git a/benches/cast_kernels.rs b/benches/cast_kernels.rs index b30ef4cc04d..a2ce32de1c5 100644 --- a/benches/cast_kernels.rs +++ b/benches/cast_kernels.rs @@ -171,6 +171,10 @@ fn add_benchmark(c: &mut Criterion) { c.bench_function("cast utf8 to date64 512", |b| { b.iter(|| cast_array(&utf8_date_time_array, DataType::Date64)) }); + + c.bench_function("cast int32 to binary 512", |b| { + b.iter(|| cast_array(&i32_array, DataType::Binary)) + }); } criterion_group!(benches, add_benchmark); diff --git a/src/compute/cast/primitive_to.rs b/src/compute/cast/primitive_to.rs index 2eea683003b..50ab5c97f2d 100644 --- a/src/compute/cast/primitive_to.rs +++ b/src/compute/cast/primitive_to.rs @@ -1,5 +1,6 @@ use std::hash::Hash; +use crate::error::Result; use crate::{ array::*, bitmap::Bitmap, @@ -7,10 +8,7 @@ use crate::{ datatypes::{DataType, TimeUnit}, temporal_conversions::*, types::NativeType, -}; -use crate::{ - error::Result, - util::{lexical_to_bytes, lexical_to_string}, + util::lexical_to_bytes_mut, }; use super::CastOptions; @@ -19,9 +17,21 @@ use super::CastOptions; pub fn primitive_to_binary( from: &PrimitiveArray, ) -> BinaryArray { - let iter = from.iter().map(|x| x.map(|x| lexical_to_bytes(*x))); - - BinaryArray::from_trusted_len_iter(iter) + let mut buffer = vec![]; + let builder = from.iter().fold( + MutableBinaryArray::::with_capacity(from.len()), + |mut builder, x| { + match x { + Some(x) => { + lexical_to_bytes_mut(*x, &mut buffer); + builder.push(Some(buffer.as_slice())); + } + None => builder.push_null(), + } + builder + }, + ); + builder.into() } pub(super) fn primitive_to_binary_dyn(from: &dyn Array) -> Result> @@ -60,9 +70,23 @@ where pub fn primitive_to_utf8( from: &PrimitiveArray, ) -> Utf8Array { - let iter = from.iter().map(|x| x.map(|x| lexical_to_string(*x))); - - Utf8Array::from_trusted_len_iter(iter) + let mut buffer = vec![]; + let builder = from.iter().fold( + MutableUtf8Array::::with_capacity(from.len()), + |mut builder, x| { + match x { + Some(x) => { + lexical_to_bytes_mut(*x, &mut buffer); + builder.push(Some(unsafe { + std::str::from_utf8_unchecked(buffer.as_slice()) + })); + } + None => builder.push_null(), + } + builder + }, + ); + builder.into() } pub(super) fn primitive_to_utf8_dyn(from: &dyn Array) -> Result>