This is an automated email from the ASF dual-hosted git repository.
paleolimbot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/sedona-db.git
The following commit(s) were added to refs/heads/main by this push:
new 0c23df25 feat(rust/sedona-testing): Add Raster Benchmarking (#297)
0c23df25 is described below
commit 0c23df25cf430edf7ccf7eea13305eeda95b33b3
Author: jp <[email protected]>
AuthorDate: Sat Nov 15 08:00:56 2025 -0800
feat(rust/sedona-testing): Add Raster Benchmarking (#297)
---
Cargo.lock | 1 +
rust/sedona-raster-functions/Cargo.toml | 9 ++++-
.../benches/native-raster-functions.rs | 27 +++++++++++++
rust/sedona-testing/src/benchmark_util.rs | 45 +++++++++++++++++++++-
4 files changed, 79 insertions(+), 3 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index e5d23c59..b6ad1c25 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5161,6 +5161,7 @@ dependencies = [
"arrow-array",
"arrow-buffer",
"arrow-schema",
+ "criterion",
"datafusion-common",
"datafusion-expr",
"sedona-common",
diff --git a/rust/sedona-raster-functions/Cargo.toml
b/rust/sedona-raster-functions/Cargo.toml
index d384e7ed..d0a2ea17 100644
--- a/rust/sedona-raster-functions/Cargo.toml
+++ b/rust/sedona-raster-functions/Cargo.toml
@@ -37,4 +37,11 @@ sedona-common = { path = "../sedona-common" }
sedona-expr = { path = "../sedona-expr" }
sedona-raster = { path = "../sedona-raster" }
sedona-schema = { path = "../sedona-schema" }
-sedona-testing = { path = "../sedona-testing" }
+
+[dev-dependencies]
+criterion = { workspace = true }
+sedona-testing = { path = "../sedona-testing", features = ["criterion"] }
+
+[[bench]]
+harness = false
+name = "native-raster-functions"
diff --git a/rust/sedona-raster-functions/benches/native-raster-functions.rs
b/rust/sedona-raster-functions/benches/native-raster-functions.rs
new file mode 100644
index 00000000..d729ccc5
--- /dev/null
+++ b/rust/sedona-raster-functions/benches/native-raster-functions.rs
@@ -0,0 +1,27 @@
+// 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 criterion::{criterion_group, criterion_main, Criterion};
+use sedona_testing::benchmark_util::{benchmark, BenchmarkArgSpec::*};
+
+fn criterion_benchmark(c: &mut Criterion) {
+ let f = sedona_raster_functions::register::default_function_set();
+
+ benchmark::scalar(c, &f, "native", "rs_width", Raster(64, 64));
+}
+
+criterion_group!(benches, criterion_benchmark);
+criterion_main!(benches);
diff --git a/rust/sedona-testing/src/benchmark_util.rs
b/rust/sedona-testing/src/benchmark_util.rs
index 6b55848d..9e94748f 100644
--- a/rust/sedona-testing/src/benchmark_util.rs
+++ b/rust/sedona-testing/src/benchmark_util.rs
@@ -26,10 +26,12 @@ use rand::{distributions::Uniform, rngs::StdRng, Rng,
SeedableRng};
use sedona_common::sedona_internal_err;
use sedona_geometry::types::GeometryTypeId;
-use sedona_schema::datatypes::{SedonaType, WKB_GEOMETRY};
+use sedona_schema::datatypes::{SedonaType, RASTER, WKB_GEOMETRY};
+use sedona_schema::raster::BandDataType;
use crate::{
datagen::RandomPartitionedDataBuilder,
+ rasters::generate_tiled_rasters,
testers::{AggregateUdfTester, ScalarUdfTester},
};
@@ -281,6 +283,8 @@ pub enum BenchmarkArgSpec {
Transformed(Box<BenchmarkArgSpec>, ScalarUDF),
/// A string that will be a constant
String(String),
+ /// Randomly generated raster input with a specified width, height
+ Raster(usize, usize),
}
// Custom implementation of Debug because otherwise the output of Transformed()
@@ -295,6 +299,7 @@ impl Debug for BenchmarkArgSpec {
Self::Float64(arg0, arg1) =>
f.debug_tuple("Float64").field(arg0).field(arg1).finish(),
Self::Transformed(inner, t) => write!(f, "{}({:?})", t.name(),
inner),
Self::String(s) => write!(f, "String({s})"),
+ Self::Raster(w, h) =>
f.debug_tuple("Raster").field(w).field(h).finish(),
}
}
}
@@ -313,6 +318,7 @@ impl BenchmarkArgSpec {
tester.return_type().unwrap()
}
BenchmarkArgSpec::String(_) => SedonaType::Arrow(DataType::Utf8),
+ BenchmarkArgSpec::Raster(_, _) => RASTER,
}
}
@@ -394,6 +400,21 @@ impl BenchmarkArgSpec {
.collect::<Result<Vec<_>>>()?;
Ok(string_array)
}
+ BenchmarkArgSpec::Raster(width, height) => {
+ let mut arrays = vec![];
+ for _ in 0..num_batches {
+ let tile_size = (*width, *height);
+ let tile_count = (rows_per_batch, 1);
+ let raster = generate_tiled_rasters(
+ tile_size,
+ tile_count,
+ BandDataType::UInt8,
+ Some(43),
+ )?;
+ arrays.push(Arc::new(raster) as ArrayRef);
+ }
+ Ok(arrays)
+ }
}
}
@@ -537,7 +558,7 @@ impl BenchmarkData {
#[cfg(test)]
mod test {
- use arrow_array::Array;
+ use arrow_array::{Array, StructArray};
use datafusion_common::cast::as_binary_array;
use datafusion_expr::{ColumnarValue, SimpleScalarUDF};
use geo_traits::Dimensions;
@@ -857,4 +878,24 @@ mod test {
assert_eq!(data.arrays[3].len(), 2);
assert_eq!(data.arrays[3][0].data_type(), &DataType::Float64);
}
+
+ #[test]
+ fn arg_spec_raster() {
+ use sedona_raster::array::RasterStructArray;
+ use sedona_raster::traits::RasterRef;
+
+ let spec = BenchmarkArgSpec::Raster(10, 5);
+ assert_eq!(spec.sedona_type(), RASTER);
+ let data = spec.build_arrays(0, 2, ROWS_PER_BATCH).unwrap();
+ assert_eq!(data.len(), 2);
+ assert_eq!(data[0].data_type(), RASTER.storage_type());
+
+ let raster_array =
data[0].as_any().downcast_ref::<StructArray>().unwrap();
+ let rasters = RasterStructArray::new(raster_array);
+ assert_eq!(rasters.len(), ROWS_PER_BATCH);
+ let raster = rasters.get(0).unwrap();
+ let metadata = raster.metadata();
+ assert_eq!(metadata.width(), 10);
+ assert_eq!(metadata.height(), 5);
+ }
}