-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: add benchmarks for varied forms of lookups #2142
Changes from 7 commits
d4c78a8
f716ba2
1531ace
1268b16
c619b93
38341f0
61d8668
0af8533
c9ed68c
432c760
c2d5cdc
7cca278
a32c1d4
20184a4
3e1de91
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
use crate::db_lookup_times_utils::{ | ||
matrix::matrix, | ||
utils::{ | ||
get_full_block, | ||
get_random_block_height, | ||
multi_get_block, | ||
open_db, | ||
open_raw_rocksdb, | ||
}, | ||
}; | ||
use criterion::{ | ||
criterion_group, | ||
criterion_main, | ||
Criterion, | ||
}; | ||
use db_lookup_times_utils::seed::{ | ||
seed_compressed_blocks_and_transactions_matrix, | ||
seed_full_block_matrix, | ||
}; | ||
use fuel_core_storage::transactional::AtomicView; | ||
use rand::thread_rng; | ||
|
||
mod db_lookup_times_utils; | ||
|
||
pub fn header_and_tx_lookup(c: &mut Criterion) { | ||
let method = "header_and_tx"; | ||
let mut rng = thread_rng(); | ||
|
||
seed_compressed_blocks_and_transactions_matrix(method); | ||
let mut group = c.benchmark_group(method); | ||
|
||
for (block_count, tx_count) in matrix() { | ||
let database = open_db(block_count, tx_count, method); | ||
let view = database.latest_view().unwrap(); | ||
group.bench_function(format!("{block_count}/{tx_count}"), |b| { | ||
b.iter(|| { | ||
let height = get_random_block_height(&mut rng, block_count); | ||
let block = view.get_full_block(&height); | ||
assert!(block.is_ok()); | ||
assert!(block.unwrap().is_some()); | ||
}); | ||
}); | ||
} | ||
|
||
group.finish(); | ||
} | ||
|
||
pub fn multi_get_lookup(c: &mut Criterion) { | ||
let method = "multi_get"; | ||
let mut rng = thread_rng(); | ||
|
||
seed_compressed_blocks_and_transactions_matrix(method); | ||
let mut group = c.benchmark_group(method); | ||
|
||
for (block_count, tx_count) in matrix() { | ||
let database = open_raw_rocksdb(block_count, tx_count, method); | ||
group.bench_function(format!("{block_count}/{tx_count}"), |b| { | ||
b.iter(|| { | ||
let height = get_random_block_height(&mut rng, block_count); | ||
assert!(multi_get_block(&database, height).is_ok()); | ||
}); | ||
}); | ||
} | ||
|
||
group.finish(); | ||
} | ||
|
||
pub fn full_block_lookup(c: &mut Criterion) { | ||
let method = "full_block"; | ||
let mut rng = thread_rng(); | ||
|
||
seed_full_block_matrix(); | ||
let mut group = c.benchmark_group(method); | ||
|
||
for (block_count, tx_count) in matrix() { | ||
let database = open_db(block_count, tx_count, method); | ||
let view = database.latest_view().unwrap(); | ||
group.bench_function(format!("{block_count}/{tx_count}"), |b| { | ||
b.iter(|| { | ||
let height = get_random_block_height(&mut rng, block_count); | ||
let full_block = get_full_block(&view, &height); | ||
assert!(full_block.is_ok()); | ||
assert!(full_block.unwrap().is_some()); | ||
}); | ||
}); | ||
} | ||
|
||
group.finish(); | ||
} | ||
|
||
criterion_group! { | ||
name = benches; | ||
config = Criterion::default().sample_size(100_000).measurement_time(std::time::Duration::from_secs(100)); | ||
targets = header_and_tx_lookup, multi_get_lookup, full_block_lookup | ||
} | ||
criterion_main!(benches); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
pub const BLOCK_COUNT_MATRIX: [u32; 2] = [10, 100]; | ||
pub const TX_COUNT_MATRIX: [u32; 2] = [100, 1000]; | ||
|
||
// todo: we can make this lazy loaded | ||
netrome marked this conversation as resolved.
Show resolved
Hide resolved
|
||
pub fn matrix() -> impl Iterator<Item = (u32, u32)> { | ||
BLOCK_COUNT_MATRIX.iter().flat_map(|&block_count| { | ||
TX_COUNT_MATRIX | ||
.iter() | ||
.map(move |&tx_count| (block_count, tx_count)) | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub mod matrix; | ||
pub mod seed; | ||
pub mod utils; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
use crate::db_lookup_times_utils::{ | ||
matrix::matrix, | ||
utils::{ | ||
chain_id, | ||
open_raw_rocksdb, | ||
}, | ||
}; | ||
use fuel_core::{ | ||
database::database_description::on_chain::OnChain, | ||
state::rocks_db::RocksDb, | ||
}; | ||
use fuel_core_storage::{ | ||
column::Column, | ||
kv_store::{ | ||
KeyValueMutate, | ||
Value, | ||
}, | ||
}; | ||
use fuel_core_types::{ | ||
blockchain::{ | ||
block::{ | ||
Block, | ||
PartialFuelBlock, | ||
}, | ||
header::{ | ||
ConsensusHeader, | ||
PartialBlockHeader, | ||
}, | ||
primitives::Empty, | ||
}, | ||
fuel_tx::{ | ||
Transaction, | ||
UniqueIdentifier, | ||
}, | ||
fuel_types::BlockHeight, | ||
}; | ||
|
||
pub fn seed_compressed_blocks_and_transactions_matrix(method: &str) { | ||
for (block_count, tx_count) in matrix() { | ||
let mut database = open_raw_rocksdb(block_count, tx_count, method); | ||
let _ = | ||
seed_compressed_blocks_and_transactions(&mut database, block_count, tx_count); | ||
} | ||
} | ||
|
||
pub fn seed_full_block_matrix() { | ||
for (block_count, tx_count) in matrix() { | ||
let mut database = open_raw_rocksdb(block_count, tx_count, "full_block"); | ||
seed_full_blocks(&mut database, block_count, tx_count); | ||
} | ||
} | ||
|
||
fn generate_bench_block(height: u32, tx_count: u32) -> Block { | ||
let header = PartialBlockHeader { | ||
application: Default::default(), | ||
consensus: ConsensusHeader::<Empty> { | ||
height: BlockHeight::from(height), | ||
..Default::default() | ||
}, | ||
}; | ||
let txes = generate_bench_transactions(tx_count); | ||
let block = PartialFuelBlock::new(header, txes); | ||
block.generate(&[], Default::default()).unwrap() | ||
} | ||
|
||
fn generate_bench_transactions(tx_count: u32) -> Vec<Transaction> { | ||
let mut txes = vec![]; | ||
for _ in 0..tx_count { | ||
txes.push(Transaction::default_test_tx()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nit] It would be nice to make transactions random to be sure that compression will not affect it too much There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lol, okay ~ will alter |
||
} | ||
txes | ||
} | ||
|
||
fn height_key(block_height: u32) -> Vec<u8> { | ||
BlockHeight::from(block_height).to_bytes().to_vec() | ||
} | ||
|
||
fn insert_compressed_block( | ||
database: &mut RocksDb<OnChain>, | ||
height: u32, | ||
tx_count: u32, | ||
) -> Block { | ||
let block = generate_bench_block(height, tx_count); | ||
|
||
let compressed_block = block.compress(&chain_id()); | ||
let height_key = height_key(height); | ||
|
||
let raw_compressed_block = postcard::to_allocvec(&compressed_block).unwrap().to_vec(); | ||
let raw_transactions = block | ||
.transactions() | ||
.iter() | ||
.map(|tx| { | ||
( | ||
tx.id(&chain_id()), | ||
postcard::to_allocvec(tx).unwrap().to_vec(), | ||
) | ||
}) | ||
.collect::<Vec<_>>(); | ||
|
||
// 1. insert into CompressedBlocks table | ||
database | ||
.put( | ||
height_key.as_slice(), | ||
Column::FuelBlocks, | ||
Value::new(raw_compressed_block), | ||
) | ||
.unwrap(); | ||
// 2. insert into Transactions table | ||
for (tx_id, tx) in raw_transactions { | ||
database | ||
.put(tx_id.as_slice(), Column::Transactions, Value::new(tx)) | ||
.unwrap(); | ||
} | ||
|
||
block | ||
} | ||
|
||
fn insert_full_block(database: &mut RocksDb<OnChain>, height: u32, tx_count: u32) { | ||
let block = insert_compressed_block(database, height, tx_count); | ||
|
||
let height_key = height_key(height); | ||
let raw_full_block = postcard::to_allocvec(&block).unwrap().to_vec(); | ||
|
||
// 3. insert into FullFuelBlocks table | ||
rymnc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
database | ||
.put( | ||
height_key.as_slice(), | ||
Column::FullFuelBlocks, | ||
Value::new(raw_full_block), | ||
) | ||
.unwrap(); | ||
} | ||
|
||
fn seed_compressed_blocks_and_transactions( | ||
database: &mut RocksDb<OnChain>, | ||
block_count: u32, | ||
tx_count: u32, | ||
) -> Vec<Block> { | ||
let mut blocks = vec![]; | ||
for block_number in 0..block_count { | ||
blocks.push(insert_compressed_block(database, block_number, tx_count)); | ||
} | ||
blocks | ||
} | ||
|
||
fn seed_full_blocks(database: &mut RocksDb<OnChain>, block_count: u32, tx_count: u32) { | ||
// we seed compressed blocks and transactions to not affect individual | ||
// lookup times | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment doesn't make sense to me inside the context of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the context is that if we do include There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand now. I think this comment should be above the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. addressed in 7cca278 |
||
|
||
for block_number in 0..block_count { | ||
insert_full_block(database, block_number, tx_count); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to clean up the database after benchmarks. If you want to keep the results there, then we can add additional ENV variable that you can set to disable clean up logic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addressed in #2159
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
precisely in https://github.com/FuelLabs/fuel-core/pull/2159/files#diff-0e0c7132cb01e4397b764c20e78657d53e9daef5be6ecd41680f45ae6aac77e6R4-R16