Skip to content

Commit

Permalink
TransactionView: parsing helper functions (#2257)
Browse files Browse the repository at this point in the history
  • Loading branch information
apfitzge authored Aug 2, 2024
1 parent 32e7881 commit 3f3f48f
Show file tree
Hide file tree
Showing 7 changed files with 450 additions and 0 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ members = [
"transaction-dos",
"transaction-metrics-tracker",
"transaction-status",
"transaction-view",
"turbine",
"type-overrides",
"udp-client",
Expand Down Expand Up @@ -159,6 +160,7 @@ edition = "2021"

[workspace.dependencies]
Inflector = "0.11.4"
agave-transaction-view = { path = "transaction-view", version = "=2.1.0" }
aquamarine = "0.3.3"
aes-gcm-siv = "0.11.1"
ahash = "0.8.10"
Expand Down
26 changes: 26 additions & 0 deletions transaction-view/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "agave-transaction-view"
description = "Agave TranactionView"
documentation = "https://docs.rs/agave-transaction-view"
version = { workspace = true }
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }

[dependencies]
solana-sdk = { workspace = true }

[dev-dependencies]
# See order-crates-for-publishing.py for using this unusual `path = "."`
agave-transaction-view = { path = ".", features = ["dev-context-only-utils"] }
bincode = { workspace = true }
criterion = { workspace = true }

[features]
dev-context-only-utils = []

[[bench]]
name = "bytes"
harness = false
90 changes: 90 additions & 0 deletions transaction-view/benches/bytes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use {
agave_transaction_view::bytes::{optimized_read_compressed_u16, read_compressed_u16},
bincode::{serialize_into, DefaultOptions, Options},
criterion::{black_box, criterion_group, criterion_main, Criterion, Throughput},
solana_sdk::{
packet::PACKET_DATA_SIZE,
short_vec::{decode_shortu16_len, ShortU16},
},
};

fn setup() -> Vec<(u16, usize, Vec<u8>)> {
let options = DefaultOptions::new().with_fixint_encoding(); // Ensure fixed-int encoding

// Create a vector of all valid u16 values serialized into 16-byte buffers.
let mut values = Vec::with_capacity(PACKET_DATA_SIZE);
for value in 0..PACKET_DATA_SIZE as u16 {
let short_u16 = ShortU16(value);
let mut buffer = vec![0u8; 16];
let serialized_len = options
.serialized_size(&short_u16)
.expect("Failed to get serialized size");
serialize_into(&mut buffer[..], &short_u16).expect("Serialization failed");
values.push((value, serialized_len as usize, buffer));
}

values
}

fn bench_u16_parsing(c: &mut Criterion) {
let values_serialized_lengths_and_buffers = setup();
let mut group = c.benchmark_group("compressed_u16_parsing");
group.throughput(Throughput::Elements(
values_serialized_lengths_and_buffers.len() as u64,
));

// Benchmark the decode_shortu16_len function from `solana-sdk`
group.bench_function("short_u16_decode", |c| {
c.iter(|| {
decode_shortu16_len_iter(&values_serialized_lengths_and_buffers);
})
});

// Benchmark `read_compressed_u16`
group.bench_function("read_compressed_u16", |c| {
c.iter(|| {
read_compressed_u16_iter(&values_serialized_lengths_and_buffers);
})
});

group.bench_function("optimized_read_compressed_u16", |c| {
c.iter(|| {
optimized_read_compressed_u16_iter(&values_serialized_lengths_and_buffers);
})
});
}

fn decode_shortu16_len_iter(values_serialized_lengths_and_buffers: &[(u16, usize, Vec<u8>)]) {
for (value, serialized_len, buffer) in values_serialized_lengths_and_buffers.iter() {
let (read_value, bytes_read) = decode_shortu16_len(black_box(buffer)).unwrap();
assert_eq!(read_value, *value as usize, "Value mismatch for: {}", value);
assert_eq!(
bytes_read, *serialized_len,
"Offset mismatch for: {}",
value
);
}
}

fn read_compressed_u16_iter(values_serialized_lengths_and_buffers: &[(u16, usize, Vec<u8>)]) {
for (value, serialized_len, buffer) in values_serialized_lengths_and_buffers.iter() {
let mut offset = 0;
let read_value = read_compressed_u16(black_box(buffer), &mut offset).unwrap();
assert_eq!(read_value, *value, "Value mismatch for: {}", value);
assert_eq!(offset, *serialized_len, "Offset mismatch for: {}", value);
}
}

fn optimized_read_compressed_u16_iter(
values_serialized_lengths_and_buffers: &[(u16, usize, Vec<u8>)],
) {
for (value, serialized_len, buffer) in values_serialized_lengths_and_buffers.iter() {
let mut offset = 0;
let read_value = optimized_read_compressed_u16(black_box(buffer), &mut offset).unwrap();
assert_eq!(read_value, *value, "Value mismatch for: {}", value);
assert_eq!(offset, *serialized_len, "Offset mismatch for: {}", value);
}
}

criterion_group!(benches, bench_u16_parsing);
criterion_main!(benches);
Loading

0 comments on commit 3f3f48f

Please sign in to comment.