Skip to content

Commit

Permalink
arrow2_convert primitive (de)serialization benchmarks (#1742)
Browse files Browse the repository at this point in the history
* arrow2_convert primitive benchmarks

* addressing PR comments
  • Loading branch information
teh-cmc authored Mar 31, 2023
1 parent c54abe0 commit 1e84aa5
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 0 deletions.
4 changes: 4 additions & 0 deletions crates/re_arrow_store/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,7 @@ required-features = ["polars"]
[[bench]]
name = "data_store"
harness = false

[[bench]]
name = "arrow2_convert"
harness = false
141 changes: 141 additions & 0 deletions crates/re_arrow_store/benches/arrow2_convert.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
//! Keeping track of performance issues/regressions in `arrow2_convert` that directly affect us.
#[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;

use arrow2::{array::PrimitiveArray, datatypes::PhysicalType, types::PrimitiveType};
use criterion::{criterion_group, criterion_main, Criterion};
use re_log_types::{
component_types::InstanceKey, external::arrow2_convert::deserialize::TryIntoCollection,
Component as _, DataCell,
};

// ---

criterion_group!(benches, serialize, deserialize);
criterion_main!(benches);

// ---

#[cfg(not(debug_assertions))]
const NUM_INSTANCES: usize = 100_000;

// `cargo test` also runs the benchmark setup code, so make sure they run quickly:
#[cfg(debug_assertions)]
const NUM_INSTANCES: usize = 1;

// ---

fn serialize(c: &mut Criterion) {
let mut group = c.benchmark_group(format!(
"arrow2_convert/serialize/primitive/instances={NUM_INSTANCES}"
));
group.throughput(criterion::Throughput::Elements(NUM_INSTANCES as _));

{
group.bench_function("arrow2_convert", |b| {
b.iter(|| {
let cell = DataCell::from_component::<InstanceKey>(0..NUM_INSTANCES as u64);
assert_eq!(NUM_INSTANCES as u32, cell.num_instances());
assert_eq!(
cell.datatype().to_physical_type(),
PhysicalType::Primitive(PrimitiveType::UInt64)
);
cell
});
});
}

{
group.bench_function("arrow2/from_values", |b| {
b.iter(|| {
let values = PrimitiveArray::from_values(0..NUM_INSTANCES as u64).boxed();
let cell = crate::DataCell::from_arrow(InstanceKey::name(), values);
assert_eq!(NUM_INSTANCES as u32, cell.num_instances());
assert_eq!(
cell.datatype().to_physical_type(),
PhysicalType::Primitive(PrimitiveType::UInt64)
);
cell
});
});
}

{
group.bench_function("arrow2/from_vec", |b| {
b.iter(|| {
// NOTE: We do the `collect()` here on purpose!
//
// All of these APIs have to allocate an array under the hood, except `from_vec`
// which is O(1) (it just unsafely reuses the vec's data pointer).
// We need to measure the collection in order to have a leveled playing field.
let values = PrimitiveArray::from_vec((0..NUM_INSTANCES as u64).collect()).boxed();
let cell = crate::DataCell::from_arrow(InstanceKey::name(), values);
assert_eq!(NUM_INSTANCES as u32, cell.num_instances());
assert_eq!(
cell.datatype().to_physical_type(),
PhysicalType::Primitive(PrimitiveType::UInt64)
);
cell
});
});
}
}

fn deserialize(c: &mut Criterion) {
let mut group = c.benchmark_group(format!(
"arrow2_convert/deserialize/primitive/instances={NUM_INSTANCES}"
));
group.throughput(criterion::Throughput::Elements(NUM_INSTANCES as _));

let cell = DataCell::from_component::<InstanceKey>(0..NUM_INSTANCES as u64);
let data = cell.as_arrow();

{
group.bench_function("arrow2_convert", |b| {
b.iter(|| {
let keys: Vec<InstanceKey> = data.as_ref().try_into_collection().unwrap();
assert_eq!(NUM_INSTANCES, keys.len());
assert_eq!(
InstanceKey(NUM_INSTANCES as u64 / 2),
keys[NUM_INSTANCES / 2]
);
keys
});
});
}

{
group.bench_function("arrow2/validity_checks", |b| {
b.iter(|| {
let data = data.as_any().downcast_ref::<PrimitiveArray<u64>>().unwrap();
let keys: Vec<InstanceKey> = data
.into_iter()
.filter_map(|v| v.copied().map(InstanceKey))
.collect();
assert_eq!(NUM_INSTANCES, keys.len());
assert_eq!(
InstanceKey(NUM_INSTANCES as u64 / 2),
keys[NUM_INSTANCES / 2]
);
keys
});
});
}

{
group.bench_function("arrow2/validity_bypass", |b| {
b.iter(|| {
let data = data.as_any().downcast_ref::<PrimitiveArray<u64>>().unwrap();
assert!(data.validity().is_none());
let keys: Vec<InstanceKey> = data.values_iter().copied().map(InstanceKey).collect();
assert_eq!(NUM_INSTANCES, keys.len());
assert_eq!(
InstanceKey(NUM_INSTANCES as u64 / 2),
keys[NUM_INSTANCES / 2]
);
keys
});
});
}
}

1 comment on commit 1e84aa5

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rust Benchmark

Benchmark suite Current: 1e84aa5 Previous: c54abe0 Ratio
arrow2_convert/serialize/primitive/instances=100000/arrow2_convert 413783 ns/iter (± 431)
arrow2_convert/serialize/primitive/instances=100000/arrow2/from_values 19536 ns/iter (± 90)
arrow2_convert/serialize/primitive/instances=100000/arrow2/from_vec 19223 ns/iter (± 53)
arrow2_convert/deserialize/primitive/instances=100000/arrow2_convert 96275 ns/iter (± 172)
arrow2_convert/deserialize/primitive/instances=100000/arrow2/validity_checks 207263 ns/iter (± 312)
arrow2_convert/deserialize/primitive/instances=100000/arrow2/validity_bypass 58066 ns/iter (± 73)
datastore/num_rows=1000/num_instances=1000/packed=false/insert/default 10145102 ns/iter (± 352522) 10718235 ns/iter (± 403013) 0.95
datastore/num_rows=1000/num_instances=1000/packed=false/insert/bucketsz=0 12048569 ns/iter (± 447633) 13635519 ns/iter (± 500386) 0.88
datastore/num_rows=1000/num_instances=1000/packed=false/insert/bucketsz=2 12051372 ns/iter (± 855402) 12337820 ns/iter (± 395662) 0.98
datastore/num_rows=1000/num_instances=1000/packed=false/insert/bucketsz=32 11358128 ns/iter (± 421011) 10876230 ns/iter (± 288112) 1.04
datastore/num_rows=1000/num_instances=1000/packed=false/insert/bucketsz=2048 10901296 ns/iter (± 419678) 10733458 ns/iter (± 387121) 1.02
datastore/num_rows=1000/num_instances=1000/packed=true/insert/default 11733745 ns/iter (± 829902) 9872101 ns/iter (± 421647) 1.19
datastore/num_rows=1000/num_instances=1000/packed=true/insert/bucketsz=0 14016063 ns/iter (± 795729) 11491660 ns/iter (± 686669) 1.22
datastore/num_rows=1000/num_instances=1000/packed=true/insert/bucketsz=2 14955978 ns/iter (± 1336712) 11653623 ns/iter (± 532616) 1.28
datastore/num_rows=1000/num_instances=1000/packed=true/insert/bucketsz=32 12090433 ns/iter (± 874399) 9904202 ns/iter (± 335085) 1.22
datastore/num_rows=1000/num_instances=1000/packed=true/insert/bucketsz=2048 11837369 ns/iter (± 869336) 9881109 ns/iter (± 455000) 1.20
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at/default 1850 ns/iter (± 16) 1836 ns/iter (± 26) 1.01
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at/bucketsz=0 1874 ns/iter (± 2) 1845 ns/iter (± 17) 1.02
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at/bucketsz=2 1856 ns/iter (± 0) 1815 ns/iter (± 23) 1.02
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at/bucketsz=32 1863 ns/iter (± 1) 1810 ns/iter (± 19) 1.03
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at/bucketsz=2048 1845 ns/iter (± 2) 1802 ns/iter (± 16) 1.02
datastore/num_rows=1000/num_instances=1000/packed=true/latest_at/default 1861 ns/iter (± 18) 1835 ns/iter (± 27) 1.01
datastore/num_rows=1000/num_instances=1000/packed=true/latest_at/bucketsz=0 1862 ns/iter (± 0) 1834 ns/iter (± 20) 1.02
datastore/num_rows=1000/num_instances=1000/packed=true/latest_at/bucketsz=2 1856 ns/iter (± 1) 1804 ns/iter (± 23) 1.03
datastore/num_rows=1000/num_instances=1000/packed=true/latest_at/bucketsz=32 1870 ns/iter (± 3) 1808 ns/iter (± 24) 1.03
datastore/num_rows=1000/num_instances=1000/packed=true/latest_at/bucketsz=2048 1868 ns/iter (± 1) 1812 ns/iter (± 22) 1.03
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at_missing/primary/default 279 ns/iter (± 0) 278 ns/iter (± 2) 1.00
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at_missing/secondaries/default 434 ns/iter (± 0) 429 ns/iter (± 4) 1.01
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at_missing/primary/bucketsz=0 280 ns/iter (± 0) 278 ns/iter (± 3) 1.01
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at_missing/secondaries/bucketsz=0 443 ns/iter (± 1) 440 ns/iter (± 4) 1.01
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at_missing/primary/bucketsz=2 281 ns/iter (± 0) 279 ns/iter (± 3) 1.01
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at_missing/secondaries/bucketsz=2 444 ns/iter (± 0) 436 ns/iter (± 6) 1.02
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at_missing/primary/bucketsz=32 280 ns/iter (± 0) 277 ns/iter (± 3) 1.01
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at_missing/secondaries/bucketsz=32 439 ns/iter (± 0) 431 ns/iter (± 6) 1.02
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at_missing/primary/bucketsz=2048 280 ns/iter (± 0) 276 ns/iter (± 3) 1.01
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at_missing/secondaries/bucketsz=2048 437 ns/iter (± 0) 428 ns/iter (± 4) 1.02
datastore/num_rows=1000/num_instances=1000/packed=true/latest_at_missing/primary/default 279 ns/iter (± 1) 276 ns/iter (± 3) 1.01
datastore/num_rows=1000/num_instances=1000/packed=true/latest_at_missing/secondaries/default 435 ns/iter (± 0) 428 ns/iter (± 5) 1.02
datastore/num_rows=1000/num_instances=1000/packed=true/latest_at_missing/primary/bucketsz=0 281 ns/iter (± 0) 277 ns/iter (± 3) 1.01
datastore/num_rows=1000/num_instances=1000/packed=true/latest_at_missing/secondaries/bucketsz=0 442 ns/iter (± 0) 438 ns/iter (± 3) 1.01
datastore/num_rows=1000/num_instances=1000/packed=true/latest_at_missing/primary/bucketsz=2 281 ns/iter (± 0) 277 ns/iter (± 3) 1.01
datastore/num_rows=1000/num_instances=1000/packed=true/latest_at_missing/secondaries/bucketsz=2 444 ns/iter (± 0) 436 ns/iter (± 5) 1.02
datastore/num_rows=1000/num_instances=1000/packed=true/latest_at_missing/primary/bucketsz=32 280 ns/iter (± 0) 277 ns/iter (± 2) 1.01
datastore/num_rows=1000/num_instances=1000/packed=true/latest_at_missing/secondaries/bucketsz=32 439 ns/iter (± 0) 431 ns/iter (± 5) 1.02
datastore/num_rows=1000/num_instances=1000/packed=true/latest_at_missing/primary/bucketsz=2048 280 ns/iter (± 0) 276 ns/iter (± 3) 1.01
datastore/num_rows=1000/num_instances=1000/packed=true/latest_at_missing/secondaries/bucketsz=2048 435 ns/iter (± 0) 438 ns/iter (± 4) 0.99
datastore/num_rows=1000/num_instances=1000/packed=false/range/default 13809707 ns/iter (± 865890) 10890880 ns/iter (± 446497) 1.27
datastore/num_rows=1000/num_instances=1000/packed=false/range/bucketsz=0 2203027 ns/iter (± 47911) 2134825 ns/iter (± 18809) 1.03
datastore/num_rows=1000/num_instances=1000/packed=false/range/bucketsz=2 2168216 ns/iter (± 46671) 2101418 ns/iter (± 19498) 1.03
datastore/num_rows=1000/num_instances=1000/packed=false/range/bucketsz=32 1875647 ns/iter (± 11106) 1891604 ns/iter (± 17723) 0.99
datastore/num_rows=1000/num_instances=1000/packed=false/range/bucketsz=2048 1883866 ns/iter (± 10031) 1832908 ns/iter (± 19090) 1.03
datastore/num_rows=1000/num_instances=1000/packed=true/range/default 10400072 ns/iter (± 431216) 10591835 ns/iter (± 540628) 0.98
datastore/num_rows=1000/num_instances=1000/packed=true/range/bucketsz=0 2194440 ns/iter (± 11960) 2135590 ns/iter (± 20298) 1.03
datastore/num_rows=1000/num_instances=1000/packed=true/range/bucketsz=2 2122026 ns/iter (± 5662) 2184293 ns/iter (± 17144) 0.97
datastore/num_rows=1000/num_instances=1000/packed=true/range/bucketsz=32 1849348 ns/iter (± 9485) 1851820 ns/iter (± 16005) 1.00
datastore/num_rows=1000/num_instances=1000/packed=true/range/bucketsz=2048 1820217 ns/iter (± 11183) 1835181 ns/iter (± 14358) 0.99
mono_points_arrow/generate_message_bundles 42867912 ns/iter (± 881100) 43217364 ns/iter (± 972079) 0.99
mono_points_arrow/generate_messages 164790626 ns/iter (± 1127918) 180881943 ns/iter (± 1799900) 0.91
mono_points_arrow/encode_log_msg 210861818 ns/iter (± 998326) 217927607 ns/iter (± 1944470) 0.97
mono_points_arrow/encode_total 416349558 ns/iter (± 2684064) 441610066 ns/iter (± 2526662) 0.94
mono_points_arrow/decode_log_msg 254511216 ns/iter (± 1527236) 263949615 ns/iter (± 1710186) 0.96
mono_points_arrow/decode_message_bundles 85936376 ns/iter (± 973463) 93398365 ns/iter (± 1209081) 0.92
mono_points_arrow/decode_total 339472936 ns/iter (± 2078519) 360239038 ns/iter (± 2421993) 0.94
mono_points_arrow_batched/generate_message_bundles 39083235 ns/iter (± 1369007) 30604243 ns/iter (± 1460648) 1.28
mono_points_arrow_batched/generate_messages 11961378 ns/iter (± 942207) 8446424 ns/iter (± 585466) 1.42
mono_points_arrow_batched/encode_log_msg 1785505 ns/iter (± 8123) 1753609 ns/iter (± 15161) 1.02
mono_points_arrow_batched/encode_total 52791770 ns/iter (± 1654431) 44022444 ns/iter (± 2211209) 1.20
mono_points_arrow_batched/decode_log_msg 986530 ns/iter (± 8005) 971979 ns/iter (± 6696) 1.01
mono_points_arrow_batched/decode_message_bundles 21011125 ns/iter (± 587571) 16561974 ns/iter (± 879038) 1.27
mono_points_arrow_batched/decode_total 21932697 ns/iter (± 577379) 18012104 ns/iter (± 1014319) 1.22
batch_points_arrow/generate_message_bundles 288944 ns/iter (± 638) 282408 ns/iter (± 3270) 1.02
batch_points_arrow/generate_messages 7657 ns/iter (± 12) 7560 ns/iter (± 88) 1.01
batch_points_arrow/encode_log_msg 396846 ns/iter (± 2785) 379770 ns/iter (± 3873) 1.04
batch_points_arrow/encode_total 704820 ns/iter (± 3761) 693533 ns/iter (± 8299) 1.02
batch_points_arrow/decode_log_msg 340736 ns/iter (± 2317) 339992 ns/iter (± 2934) 1.00
batch_points_arrow/decode_message_bundles 2893 ns/iter (± 3) 2792 ns/iter (± 34) 1.04
batch_points_arrow/decode_total 347903 ns/iter (± 1754) 345523 ns/iter (± 2092) 1.01
arrow_mono_points/insert 6088436739 ns/iter (± 56078824) 6760638375 ns/iter (± 19342682) 0.90
arrow_mono_points/query 1885234 ns/iter (± 56053) 1731806 ns/iter (± 17891) 1.09
arrow_batch_points/insert 3016247 ns/iter (± 37425) 2923103 ns/iter (± 29055) 1.03
arrow_batch_points/query 16977 ns/iter (± 18) 16712 ns/iter (± 205) 1.02
arrow_batch_vecs/insert 43603 ns/iter (± 78) 43032 ns/iter (± 516) 1.01
arrow_batch_vecs/query 535280 ns/iter (± 260) 523905 ns/iter (± 6903) 1.02
tuid/Tuid::random 34 ns/iter (± 0) 34 ns/iter (± 0) 1

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.