From 27f2198bf35f8b46c32a7cb3d5b336c5bb7fab34 Mon Sep 17 00:00:00 2001 From: Kirill Fomichev Date: Wed, 20 Nov 2024 13:21:36 +0200 Subject: [PATCH] add benchmark --- Cargo.lock | 205 ++++++++++++++++++ Cargo.toml | 1 + yellowstone-grpc-proto/Cargo.toml | 9 + yellowstone-grpc-proto/benches/encode.rs | 117 ++++++++++ .../src/plugin/filter/message.rs | 4 +- 5 files changed, 335 insertions(+), 1 deletion(-) create mode 100644 yellowstone-grpc-proto/benches/encode.rs diff --git a/Cargo.lock b/Cargo.lock index daf15600..ea3665dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -126,6 +126,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + [[package]] name = "anstream" version = "0.6.15" @@ -717,6 +723,12 @@ dependencies = [ "url", ] +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cc" version = "1.1.8" @@ -754,6 +766,33 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "cipher" version = "0.4.4" @@ -896,6 +935,42 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "is-terminal", + "itertools 0.10.5", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools 0.10.5", +] + [[package]] name = "crossbeam-channel" version = "0.5.13" @@ -905,6 +980,25 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.20" @@ -1472,6 +1566,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hash32" version = "0.2.1" @@ -1529,6 +1633,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -1857,6 +1967,17 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is-terminal" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +dependencies = [ + "hermit-abi 0.4.0", + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -2237,6 +2358,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "oorandom" +version = "11.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" + [[package]] name = "opaque-debug" version = "0.3.1" @@ -2356,6 +2483,34 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + [[package]] name = "polyval" version = "0.6.2" @@ -2686,6 +2841,26 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.5.3" @@ -2908,6 +3083,15 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.23" @@ -3880,6 +4064,16 @@ dependencies = [ "time-core", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -4293,6 +4487,16 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -4721,6 +4925,7 @@ dependencies = [ "bincode", "bs58", "bytes", + "criterion", "prost 0.11.9", "prost 0.13.1", "protobuf-src", diff --git a/Cargo.toml b/Cargo.toml index 35a55a3d..5eb8514f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ bytes = "1.3.0" cargo-lock = "9.0.0" chrono = "0.4.26" clap = "4.3.0" +criterion = "0.5.1" crossbeam-channel = "0.5.8" env_logger = "0.11.3" futures = "0.3.24" diff --git a/yellowstone-grpc-proto/Cargo.toml b/yellowstone-grpc-proto/Cargo.toml index 7723e99d..48cb5c09 100644 --- a/yellowstone-grpc-proto/Cargo.toml +++ b/yellowstone-grpc-proto/Cargo.toml @@ -10,6 +10,11 @@ license = "Apache-2.0" keywords = { workspace = true } publish = true +[[bench]] +name = "encode" +harness = false +required-features = ["plugin-bench"] + [dependencies] agave-geyser-plugin-interface = { workspace = true, optional = true } base64 = { workspace = true, optional = true } @@ -17,9 +22,11 @@ bincode = { workspace = true, optional = true } bs58 = { workspace = true, optional = true } bytes = { workspace = true, optional = true } prost = { workspace = true } +prost_011 = { workspace = true, optional = true } serde = { workspace = true, optional = true } solana-account-decoder = { workspace = true, optional = true } solana-sdk = { workspace = true, optional = true } +solana-storage-proto = { workspace = true, optional = true } solana-transaction-status = { workspace = true, optional = true } smallvec = { workspace = true, optional = true } spl-token-2022 = { workspace = true, optional = true } @@ -27,6 +34,7 @@ thiserror = { workspace = true, optional = true } tonic = { workspace = true } [dev-dependencies] +criterion = { workspace = true } prost_011 = { workspace = true } solana-storage-proto = { workspace = true } @@ -54,6 +62,7 @@ plugin = [ "dep:spl-token-2022", "dep:thiserror" ] +plugin-bench = ["plugin", "dep:prost_011", "dep:solana-storage-proto"] tonic-compression = ["tonic/gzip", "tonic/zstd"] [lints] diff --git a/yellowstone-grpc-proto/benches/encode.rs b/yellowstone-grpc-proto/benches/encode.rs new file mode 100644 index 00000000..0c835ab4 --- /dev/null +++ b/yellowstone-grpc-proto/benches/encode.rs @@ -0,0 +1,117 @@ +use { + criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}, + prost::Message as _, + std::time::Duration, + yellowstone_grpc_proto::plugin::{ + filter::message::{ + tests::{ + create_accounts, create_message_filters, load_predefined_blocks, + load_predefined_transactions, + }, + FilteredUpdate, FilteredUpdateOneof, + }, + message::MessageTransaction, + }, +}; + +fn bench_account(c: &mut Criterion) { + let filters = create_message_filters(&["my special filter"]); + + let updates = create_accounts() + .into_iter() + .map(|(msg, data_slice)| FilteredUpdate { + filters: filters.clone(), + message: FilteredUpdateOneof::account(&msg, data_slice), + }) + .collect::>(); + c.bench_with_input( + BenchmarkId::new("accounts", "ref"), + &updates, + |b, updates| { + b.iter(|| { + for update in updates.iter() { + update.encode_to_vec().len(); + } + }) + }, + ); + c.bench_with_input( + BenchmarkId::new("accounts", "prost"), + &updates, + |b, updates| { + b.iter(|| { + for update in updates.iter() { + update.as_subscribe_update().encode_to_vec().len(); + } + }) + }, + ); + + let updates = load_predefined_transactions() + .into_iter() + .map(|transaction| FilteredUpdate { + filters: filters.clone(), + message: FilteredUpdateOneof::transaction(&MessageTransaction { + transaction, + slot: 42, + }), + }) + .collect::>(); + c.bench_with_input( + BenchmarkId::new("transactions", "ref"), + &updates, + |b, updates| { + b.iter(|| { + for update in updates.iter() { + update.encode_to_vec().len(); + } + }) + }, + ); + c.bench_with_input( + BenchmarkId::new("transactions", "prost"), + &updates, + |b, updates| { + b.iter(|| { + for update in updates.iter() { + update.as_subscribe_update().encode_to_vec().len(); + } + }) + }, + ); + + let updates = load_predefined_blocks() + .into_iter() + .map(|block| FilteredUpdate { + filters: filters.clone(), + message: FilteredUpdateOneof::block(Box::new(block)), + }) + .collect::>(); + c.bench_with_input(BenchmarkId::new("blocks", "ref"), &updates, |b, updates| { + b.iter(|| { + for update in updates.iter() { + update.encode_to_vec().len(); + } + }) + }); + c.bench_with_input( + BenchmarkId::new("blocks", "prost"), + &updates, + |b, updates| { + b.iter(|| { + for update in updates.iter() { + update.as_subscribe_update().encode_to_vec().len(); + } + }) + }, + ); +} + +criterion_group!( + name = benches; + config = Criterion::default() + .warm_up_time(Duration::from_secs(3)) // default 3 + .measurement_time(Duration::from_secs(5)); // default 5 + targets = bench_account +); +criterion_main!(benches); diff --git a/yellowstone-grpc-proto/src/plugin/filter/message.rs b/yellowstone-grpc-proto/src/plugin/filter/message.rs index 27c75b16..8f9710db 100644 --- a/yellowstone-grpc-proto/src/plugin/filter/message.rs +++ b/yellowstone-grpc-proto/src/plugin/filter/message.rs @@ -927,8 +927,10 @@ impl FilteredUpdateEntry { } } -#[cfg(test)] +#[cfg(any(test, feature = "plugin-bench"))] pub mod tests { + #![cfg_attr(feature = "plugin-bench", allow(dead_code))] + #![cfg_attr(feature = "plugin-bench", allow(unused_imports))] use { super::{FilteredUpdate, FilteredUpdateBlock, FilteredUpdateFilters, FilteredUpdateOneof}, crate::{