#![allow(clippy::integer_arithmetic)] #![feature(test)] extern crate test; use bincode::{deserialize, serialize}; use gemachain_ledger::{ blockstore::Blockstore, blockstore_db::{columns as cf, LedgerColumn}, get_tmp_ledger_path, }; use gemachain_runtime::bank::RewardType; use gemachain_sdk::{clock::Slot, pubkey}; use gemachain_transaction_status::{Reward, Rewards}; use std::path::Path; use test::Bencher; fn create_rewards() -> Rewards { (0..100) .map(|i| Reward { pubkey: pubkey::new_rand().to_string(), carats: 42 + i, post_balance: std::u64::MAX, reward_type: Some(RewardType::Fee), commission: None, }) .collect() } fn write_bincode_rewards(rewards_cf: &LedgerColumn, slot: Slot, rewards: Rewards) { let data = serialize(&rewards).unwrap(); rewards_cf.put_bytes(slot, &data).unwrap(); } fn write_protobuf_rewards(rewards_cf: &LedgerColumn, slot: Slot, rewards: Rewards) { let rewards = rewards.into(); rewards_cf.put_protobuf(slot, &rewards).unwrap(); } fn read_bincode_rewards(rewards_cf: &LedgerColumn, slot: Slot) -> Option { rewards_cf .get_bytes(slot) .unwrap() .map(|data| deserialize::(&data).unwrap()) } fn read_protobuf_rewards(rewards_cf: &LedgerColumn, slot: Slot) -> Option { rewards_cf.get_protobuf(slot).unwrap().map(|r| r.into()) } fn bench_write_rewards(bench: &mut Bencher, ledger_path: &Path, write_method: F) where F: Fn(&LedgerColumn, Slot, Rewards), { let blockstore = Blockstore::open(ledger_path).expect("Expected to be able to open database ledger"); let rewards = create_rewards(); let mut slot = 0; let rewards_cf = blockstore.db().column::(); bench.iter(move || { write_method(&rewards_cf, slot, rewards.clone()); slot += 1; }); Blockstore::destroy(ledger_path).expect("Expected successful database destruction"); } fn bench_read_rewards( bench: &mut Bencher, ledger_path: &Path, write_method: F, read_method: G, ) where F: Fn(&LedgerColumn, Slot, Rewards), G: Fn(&LedgerColumn, Slot) -> Option, { let blockstore = Blockstore::open(ledger_path).expect("Expected to be able to open database ledger"); let rewards = create_rewards(); let slot = 1; let rewards_cf = blockstore.db().column::(); write_method(&rewards_cf, slot, rewards); bench.iter(move || read_method(&rewards_cf, slot)); Blockstore::destroy(ledger_path).expect("Expected successful database destruction"); } #[bench] fn bench_serialize_write_bincode(bencher: &mut Bencher) { let ledger_path = get_tmp_ledger_path!(); bench_write_rewards(bencher, &ledger_path, write_bincode_rewards); } #[bench] fn bench_serialize_write_protobuf(bencher: &mut Bencher) { let ledger_path = get_tmp_ledger_path!(); bench_write_rewards(bencher, &ledger_path, write_protobuf_rewards); } #[bench] fn bench_read_bincode(bencher: &mut Bencher) { let ledger_path = get_tmp_ledger_path!(); bench_read_rewards( bencher, &ledger_path, write_bincode_rewards, read_bincode_rewards, ); } #[bench] fn bench_read_protobuf(bencher: &mut Bencher) { let ledger_path = get_tmp_ledger_path!(); bench_read_rewards( bencher, &ledger_path, write_protobuf_rewards, read_protobuf_rewards, ); }