Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Added compute::arity_assign #1070

Merged
merged 1 commit into from
Jun 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion benches/assign_ops.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use criterion::{criterion_group, criterion_main, Criterion};

use arrow2::{compute::arithmetics::basic::mul_scalar, util::bench_util::create_primitive_array};
use arrow2::compute::arity_assign::binary;
use arrow2::{
compute::arithmetics::basic::{mul, mul_scalar},
util::bench_util::*,
};

fn add_benchmark(c: &mut Criterion) {
(10..=20).step_by(2).for_each(|log2_size| {
Expand All @@ -22,6 +26,26 @@ fn add_benchmark(c: &mut Criterion) {
assert!(!a.value(10).is_nan());
})
});

let mut arr_a = create_primitive_array::<f32>(size, 0.2);
let mut arr_b = create_primitive_array_with_seed::<f32>(size, 0.2, 10);
// convert to be close to 1.01
arr_b.apply_values(|x| x.iter_mut().for_each(|x| *x = 1.01 + *x / 20.0));

c.bench_function(&format!("apply_mul null 2^{}", log2_size), |b| {
b.iter(|| {
binary(criterion::black_box(&mut arr_a), &arr_b, |x, y| x * y);
assert!(!arr_a.value(10).is_nan());
})
});

let arr_a = create_primitive_array::<f32>(size, 0.2);
c.bench_function(&format!("mul null 2^{}", log2_size), |b| {
b.iter(|| {
let a = mul(criterion::black_box(&arr_a), &arr_b);
assert!(!a.value(10).is_nan());
})
});
});
}

Expand Down
57 changes: 57 additions & 0 deletions src/compute/arity_assign.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//! Defines generics suitable to perform operations to [`PrimitiveArray`] in-place.

use super::utils::check_same_len;
use crate::{array::PrimitiveArray, types::NativeType};

/// Applies an unary function to a [`PrimitiveArray`] in-place via cow semantics.
///
/// # Implementation
/// This is the fastest method to apply a binary operation and it is often vectorized (SIMD).
/// # Panics
/// This function panics iff
/// * the arrays have a different length.
/// * the function itself panics.
#[inline]
pub fn unary<I, F>(array: &mut PrimitiveArray<I>, op: F)
where
I: NativeType,
F: Fn(I) -> I,
{
array.apply_values(|values| values.iter_mut().for_each(|v| *v = op(*v)));
}

/// Applies a binary operations to two [`PrimitiveArray`], applying the operation
/// in-place to the `lhs` via cow semantics.
///
/// # Implementation
/// This is the fastest way to perform a binary operation and it is often vectorized (SIMD).
/// # Panics
/// This function panics iff
/// * the arrays have a different length.
/// * the function itself panics.
#[inline]
pub fn binary<T, D, F>(lhs: &mut PrimitiveArray<T>, rhs: &PrimitiveArray<D>, op: F)
where
T: NativeType,
D: NativeType,
F: Fn(T, D) -> T,
{
check_same_len(lhs, rhs).unwrap();

match rhs.validity() {
None => {}
Some(rhs) => {
if lhs.validity().is_none() {
*lhs = lhs.with_validity(Some(rhs.clone()))
} else {
lhs.apply_validity(|mut lhs| lhs &= rhs)
}
}
}

lhs.apply_values(|x| {
x.iter_mut()
.zip(rhs.values().iter())
.for_each(|(l, r)| *l = op(*l, *r))
});
}
1 change: 1 addition & 0 deletions src/compute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub mod aggregate;
#[cfg_attr(docsrs, doc(cfg(feature = "compute_arithmetics")))]
pub mod arithmetics;
pub mod arity;
pub mod arity_assign;
#[cfg(feature = "compute_bitwise")]
#[cfg_attr(docsrs, doc(cfg(feature = "compute_bitwise")))]
pub mod bitwise;
Expand Down
21 changes: 21 additions & 0 deletions tests/it/compute/arity_assign.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use arrow2::array::Int32Array;
use arrow2::compute::arity_assign::{binary, unary};

#[test]
fn test_unary_assign() {
let mut a = Int32Array::from([Some(5), Some(6), None, Some(10)]);

unary(&mut a, |x| x + 10);

assert_eq!(a, Int32Array::from([Some(15), Some(16), None, Some(20)]))
}

#[test]
fn test_binary_assign() {
let mut a = Int32Array::from([Some(5), Some(6), None, Some(10)]);
let b = Int32Array::from([Some(1), Some(2), Some(1), None]);

binary(&mut a, &b, |x, y| x + y);

assert_eq!(a, Int32Array::from([Some(6), Some(8), None, None]))
}
2 changes: 2 additions & 0 deletions tests/it/compute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,5 @@ mod temporal;
mod utf8;
#[cfg(feature = "compute_window")]
mod window;

mod arity_assign;