Skip to content

Commit 1582e8d

Browse files
authored
Optimize iszero function (3-5x faster) (#12881)
* add bench * Optimize iszero function (3-5x) faster
1 parent e7ac843 commit 1582e8d

File tree

3 files changed

+60
-15
lines changed

3 files changed

+60
-15
lines changed

datafusion/functions/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ harness = false
117117
name = "make_date"
118118
required-features = ["datetime_expressions"]
119119

120+
[[bench]]
121+
harness = false
122+
name = "iszero"
123+
required-features = ["math_expressions"]
124+
120125
[[bench]]
121126
harness = false
122127
name = "nullif"
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
extern crate criterion;
19+
20+
use arrow::{
21+
datatypes::{Float32Type, Float64Type},
22+
util::bench_util::create_primitive_array,
23+
};
24+
use criterion::{black_box, criterion_group, criterion_main, Criterion};
25+
use datafusion_expr::ColumnarValue;
26+
use datafusion_functions::math::iszero;
27+
use std::sync::Arc;
28+
29+
fn criterion_benchmark(c: &mut Criterion) {
30+
let iszero = iszero();
31+
for size in [1024, 4096, 8192] {
32+
let f32_array = Arc::new(create_primitive_array::<Float32Type>(size, 0.2));
33+
let f32_args = vec![ColumnarValue::Array(f32_array)];
34+
c.bench_function(&format!("iszero f32 array: {}", size), |b| {
35+
b.iter(|| black_box(iszero.invoke(&f32_args).unwrap()))
36+
});
37+
let f64_array = Arc::new(create_primitive_array::<Float64Type>(size, 0.2));
38+
let f64_args = vec![ColumnarValue::Array(f64_array)];
39+
c.bench_function(&format!("iszero f64 array: {}", size), |b| {
40+
b.iter(|| black_box(iszero.invoke(&f64_args).unwrap()))
41+
});
42+
}
43+
}
44+
45+
criterion_group!(benches, criterion_benchmark);
46+
criterion_main!(benches);

datafusion/functions/src/math/iszero.rs

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
use std::any::Any;
1919
use std::sync::Arc;
2020

21-
use arrow::array::{ArrayRef, BooleanArray, Float32Array, Float64Array};
22-
use arrow::datatypes::DataType;
21+
use arrow::array::{ArrayRef, AsArray, BooleanArray};
2322
use arrow::datatypes::DataType::{Boolean, Float32, Float64};
23+
use arrow::datatypes::{DataType, Float32Type, Float64Type};
2424

25-
use datafusion_common::{exec_err, DataFusionError, Result};
25+
use datafusion_common::{exec_err, Result};
2626
use datafusion_expr::ColumnarValue;
2727
use datafusion_expr::TypeSignature::Exact;
2828
use datafusion_expr::{ScalarUDFImpl, Signature, Volatility};
@@ -77,20 +77,14 @@ impl ScalarUDFImpl for IsZeroFunc {
7777
/// Iszero SQL function
7878
pub fn iszero(args: &[ArrayRef]) -> Result<ArrayRef> {
7979
match args[0].data_type() {
80-
Float64 => Ok(Arc::new(make_function_scalar_inputs_return_type!(
81-
&args[0],
82-
"x",
83-
Float64Array,
84-
BooleanArray,
85-
{ |x: f64| { x == 0_f64 } }
80+
Float64 => Ok(Arc::new(BooleanArray::from_unary(
81+
args[0].as_primitive::<Float64Type>(),
82+
|x| x == 0.0,
8683
)) as ArrayRef),
8784

88-
Float32 => Ok(Arc::new(make_function_scalar_inputs_return_type!(
89-
&args[0],
90-
"x",
91-
Float32Array,
92-
BooleanArray,
93-
{ |x: f32| { x == 0_f32 } }
85+
Float32 => Ok(Arc::new(BooleanArray::from_unary(
86+
args[0].as_primitive::<Float32Type>(),
87+
|x| x == 0.0,
9488
)) as ArrayRef),
9589

9690
other => exec_err!("Unsupported data type {other:?} for function iszero"),

0 commit comments

Comments
 (0)