diff --git a/benches/main.rs b/benches/main.rs index 9fc90ff..73f62c1 100644 --- a/benches/main.rs +++ b/benches/main.rs @@ -1,5 +1,5 @@ use criterion::{Criterion, criterion_group, criterion_main}; -use eccodes::FallibleIterator; +use eccodes::{FallibleIterator, KeyRead}; use eccodes::codes_file::{CodesFile, ProductKind}; use std::hint::black_box; use std::path::Path; @@ -28,6 +28,14 @@ pub fn key_reading(c: &mut Criterion) { b.iter(|| msg.read_key_dynamic(black_box("values")).unwrap()) }); + c.bench_function("static double array reading", |b| { + b.iter(|| -> Vec { msg.read_key(black_box("values")).unwrap() }) + }); + + c.bench_function("static float array reading", |b| { + b.iter(|| -> Vec { msg.read_key(black_box("values")).unwrap() }) + }); + c.bench_function("string reading", |b| { b.iter(|| msg.read_key_dynamic(black_box("name")).unwrap()) }); diff --git a/src/codes_message/read.rs b/src/codes_message/read.rs index 890297f..1254d07 100644 --- a/src/codes_message/read.rs +++ b/src/codes_message/read.rs @@ -4,8 +4,9 @@ use crate::{ codes_message::CodesMessage, errors::CodesError, intermediate_bindings::{ - NativeKeyType, codes_get_bytes, codes_get_double, codes_get_double_array, codes_get_long, - codes_get_long_array, codes_get_native_type, codes_get_size, codes_get_string, + NativeKeyType, codes_get_bytes, codes_get_double, codes_get_double_array, + codes_get_float_array, codes_get_long, codes_get_long_array, codes_get_native_type, + codes_get_size, codes_get_string, }, }; @@ -113,6 +114,13 @@ macro_rules! key_size_check { impl_key_read!(scalar, codes_get_long, NativeKeyType::Long, i64); impl_key_read!(scalar, codes_get_double, NativeKeyType::Double, f64); +// Double-typed ecCodes arrays can be decoded directly into f32. +impl_key_read!( + array, + codes_get_float_array, + NativeKeyType::Double, + Vec +); impl_key_read!(array, codes_get_string, NativeKeyType::Str, String); impl_key_read!(array, codes_get_bytes, NativeKeyType::Bytes, Vec); impl_key_read!(array, codes_get_long_array, NativeKeyType::Long, Vec); diff --git a/src/intermediate_bindings/codes_get.rs b/src/intermediate_bindings/codes_get.rs index 82ae4f7..7380254 100644 --- a/src/intermediate_bindings/codes_get.rs +++ b/src/intermediate_bindings/codes_get.rs @@ -95,6 +95,30 @@ pub unsafe fn codes_get_double_array( } } +pub unsafe fn codes_get_float_array( + handle: *const codes_handle, + key: &str, +) -> Result, CodesError> { + unsafe { + pointer_guard::non_null!(handle); + + let mut key_size = codes_get_size(handle, key)?; + let key = CString::new(key).unwrap(); + + let mut key_values: Vec = vec![0.0; key_size]; + + let error_code = eccodes_sys::codes_get_float_array( + handle, + key.as_ptr(), + key_values.as_mut_ptr().cast(), + &raw mut key_size, + ); + error_code_to_result(error_code)?; + + Ok(key_values) + } +} + pub unsafe fn codes_get_long_array( handle: *const codes_handle, key: &str, diff --git a/src/intermediate_bindings/mod.rs b/src/intermediate_bindings/mod.rs index 0338c1b..23da50b 100644 --- a/src/intermediate_bindings/mod.rs +++ b/src/intermediate_bindings/mod.rs @@ -26,8 +26,8 @@ pub enum NativeKeyType { } pub use codes_get::{ - codes_get_bytes, codes_get_double, codes_get_double_array, codes_get_long, - codes_get_long_array, codes_get_message, codes_get_native_type, codes_get_size, + codes_get_bytes, codes_get_double, codes_get_double_array, codes_get_float_array, + codes_get_long, codes_get_long_array, codes_get_message, codes_get_native_type, codes_get_size, codes_get_string, }; pub use codes_handle::{codes_handle_clone, codes_handle_delete, codes_handle_new_from_file};