solana/accounts-bench/src/main.rs

163 lines
5.5 KiB
Rust

#![allow(clippy::integer_arithmetic)]
#[macro_use]
extern crate log;
use {
clap::{crate_description, crate_name, value_t, App, Arg},
rayon::prelude::*,
solana_measure::measure::Measure,
solana_runtime::{
accounts::Accounts,
accounts_db::{
test_utils::{create_test_accounts, update_accounts_bench},
AccountShrinkThreshold, CalcAccountsHashDataSource, INCLUDE_SLOT_IN_HASH_TESTS,
},
accounts_index::AccountSecondaryIndexes,
ancestors::Ancestors,
rent_collector::RentCollector,
},
solana_sdk::{
genesis_config::ClusterType, pubkey::Pubkey, sysvar::epoch_schedule::EpochSchedule,
},
std::{env, fs, path::PathBuf},
};
fn main() {
solana_logger::setup();
let matches = App::new(crate_name!())
.about(crate_description!())
.version(solana_version::version!())
.arg(
Arg::with_name("num_slots")
.long("num_slots")
.takes_value(true)
.value_name("SLOTS")
.help("Number of slots to store to."),
)
.arg(
Arg::with_name("num_accounts")
.long("num_accounts")
.takes_value(true)
.value_name("NUM_ACCOUNTS")
.help("Total number of accounts"),
)
.arg(
Arg::with_name("iterations")
.long("iterations")
.takes_value(true)
.value_name("ITERATIONS")
.help("Number of bench iterations"),
)
.arg(
Arg::with_name("clean")
.long("clean")
.takes_value(false)
.help("Run clean"),
)
.get_matches();
let num_slots = value_t!(matches, "num_slots", usize).unwrap_or(4);
let num_accounts = value_t!(matches, "num_accounts", usize).unwrap_or(10_000);
let iterations = value_t!(matches, "iterations", usize).unwrap_or(20);
let clean = matches.is_present("clean");
println!("clean: {clean:?}");
let path = PathBuf::from(env::var("FARF_DIR").unwrap_or_else(|_| "farf".to_owned()))
.join("accounts-bench");
println!("cleaning file system: {path:?}");
if fs::remove_dir_all(path.clone()).is_err() {
println!("Warning: Couldn't remove {path:?}");
}
let accounts = Accounts::new_with_config_for_benches(
vec![path],
&ClusterType::Testnet,
AccountSecondaryIndexes::default(),
AccountShrinkThreshold::default(),
);
println!("Creating {num_accounts} accounts");
let mut create_time = Measure::start("create accounts");
let pubkeys: Vec<_> = (0..num_slots)
.into_par_iter()
.map(|slot| {
let mut pubkeys: Vec<Pubkey> = vec![];
create_test_accounts(
&accounts,
&mut pubkeys,
num_accounts / num_slots,
slot as u64,
);
pubkeys
})
.collect();
let pubkeys: Vec<_> = pubkeys.into_iter().flatten().collect();
create_time.stop();
println!(
"created {} accounts in {} slots {}",
(num_accounts / num_slots) * num_slots,
num_slots,
create_time
);
let mut ancestors = Vec::with_capacity(num_slots);
ancestors.push(0);
for i in 1..num_slots {
ancestors.push(i as u64);
accounts.add_root(i as u64);
}
let ancestors = Ancestors::from(ancestors);
let mut elapsed = vec![0; iterations];
let mut elapsed_store = vec![0; iterations];
for x in 0..iterations {
if clean {
let mut time = Measure::start("clean");
accounts.accounts_db.clean_accounts_for_tests();
time.stop();
println!("{time}");
for slot in 0..num_slots {
update_accounts_bench(&accounts, &pubkeys, ((x + 1) * num_slots + slot) as u64);
accounts.add_root((x * num_slots + slot) as u64);
}
} else {
let mut pubkeys: Vec<Pubkey> = vec![];
let mut time = Measure::start("hash");
let results = accounts
.accounts_db
.update_accounts_hash_for_tests(0, &ancestors, false, false);
time.stop();
let mut time_store = Measure::start("hash using store");
let results_store = accounts.accounts_db.update_accounts_hash(
CalcAccountsHashDataSource::Storages,
false,
solana_sdk::clock::Slot::default(),
&ancestors,
None,
&EpochSchedule::default(),
&RentCollector::default(),
true,
INCLUDE_SLOT_IN_HASH_TESTS,
);
time_store.stop();
if results != results_store {
error!("results different: \n{:?}\n{:?}", results, results_store);
}
println!(
"hash,{},{},{},{}%",
results.0 .0,
time,
time_store,
(time_store.as_us() as f64 / time.as_us() as f64 * 100.0f64) as u32
);
create_test_accounts(&accounts, &mut pubkeys, 1, 0);
elapsed[x] = time.as_us();
elapsed_store[x] = time_store.as_us();
}
}
for x in elapsed {
info!("update_accounts_hash(us),{}", x);
}
for x in elapsed_store {
info!("calculate_accounts_hash_from_storages(us),{}", x);
}
}