Skip to content
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

[benchmarks] Add post and comment writers #705 #706

Merged
merged 4 commits into from
Aug 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions agdb_benchmarks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ categories = ["database", "database-implementations"]
[dependencies]
agdb = { version = "0.4.1", path = "../agdb" }
num-format = "0.4.4"
tokio = { version = "1.32.0", features = ["full"] }
13 changes: 6 additions & 7 deletions agdb_benchmarks/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@ use crate::BENCH_DATABASE;
use crate::CELL_PADDING;
use crate::PADDING;
use agdb::Db;
use agdb::QueryBuilder;
use std::sync::Arc;
use std::sync::RwLock;

#[derive(Clone)]
pub(crate) struct Database(pub(crate) Arc<RwLock<Db>>);

impl Database {
pub(crate) fn new() -> BenchResult<Self> {
remove_db_files();
let db = Db::new(BENCH_DATABASE)?;
let mut db = Db::new(BENCH_DATABASE)?;
db.exec_mut(&QueryBuilder::insert().nodes().aliases("users").query())?;
db.exec_mut(&QueryBuilder::insert().nodes().aliases("posts").query())?;
Ok(Self(Arc::new(RwLock::new(db))))
}

Expand All @@ -29,13 +33,8 @@ impl Database {
format_size(original_size),
format_size(db_size)
);
Ok(())
}
}

impl Drop for Database {
fn drop(&mut self) {
remove_db_files()
Ok(())
}
}

Expand Down
45 changes: 37 additions & 8 deletions agdb_benchmarks/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,54 @@
use crate::database::Database;
use bench_result::BenchResult;
use num_format::Locale;
use users::setup_users;
use std::time::Duration;

mod bench_error;
mod bench_result;
mod database;
mod users;
mod utilities;
mod writers;

pub(crate) const BENCH_DATABASE: &str = "db.agdb";
pub(crate) const LOCALE: Locale = Locale::cs;
pub(crate) const USER_COUNT: u32 = 10_000;
pub(crate) const PADDING: usize = 25;
pub(crate) const CELL_PADDING: usize = 10;
pub(crate) const PADDING: usize = 30;
pub(crate) const CELL_PADDING: usize = 8;

fn main() -> BenchResult<()> {
println!("Running agdb benchmark");
println!("---");
pub(crate) const USER_COUNT: u32 = 1000;

pub(crate) const POST_WRITER_COUNT: u32 = 100;
pub(crate) const POSTS_PER_WRITER: u32 = 100;
pub(crate) const POST_TITLE: &str = "Title of the testing post";
pub(crate) const POST_BODY: &str = "Body of the testing post should be longer than the title";

pub(crate) const COMMENT_WRITER_COUNT: u32 = 100;
pub(crate) const COMMENTS_PER_WRITER: u32 = 100;
pub(crate) const COMMENT_BODY: &str = "This is a testing comment of a post.";

pub(crate) const WRITE_DELAY: Duration = Duration::from_millis(0);

#[tokio::main]
async fn main() -> BenchResult<()> {
println!("Running agdb benchmark\n\n");
utilities::print_header();

let mut db = Database::new()?;
setup_users(&mut db)?;
users::setup_users(&mut db)?;
let mut posters = writers::start_post_writers(&mut db)?;
let mut commenters = writers::start_comment_writers(&mut db)?;

posters
.join_and_report(&format!(
"{POST_WRITER_COUNT} posters * {POSTS_PER_WRITER} posts"
))
.await?;
commenters
.join_and_report(&format!(
"{POST_WRITER_COUNT} commenters * {COMMENTS_PER_WRITER} comments"
))
.await?;

println!("---");
db.stat()
}
20 changes: 8 additions & 12 deletions agdb_benchmarks/src/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,13 @@ pub(crate) fn setup_users(db: &mut Database) -> BenchResult<()> {
let mut db = db.0.write()?;

print_flush(format!(
"{:PADDING$} | ",
format!(
"Creating users ({})",
USER_COUNT.to_formatted_string(&LOCALE)
)
"{:PADDING$} | {:CELL_PADDING$} |",
"Creating users",
USER_COUNT.to_formatted_string(&LOCALE)
));

let duration = measured(|| {
db.transaction_mut(|t| {
t.exec_mut(&QueryBuilder::insert().nodes().aliases("users").query())?;

let mut user_ids = vec![];

for i in 0..USER_COUNT {
Expand Down Expand Up @@ -61,12 +57,12 @@ pub(crate) fn setup_users(db: &mut Database) -> BenchResult<()> {
Ok(())
})?;

let per_write = duration / USER_COUNT;

print_flush(format!(
"{:CELL_PADDING$} | {} (per user)\n",
format_duration(duration),
format_duration(per_write),
" {:CELL_PADDING$} | {:CELL_PADDING$} | {:CELL_PADDING$} | {:CELL_PADDING$}\n",
"",
format_duration(duration / USER_COUNT),
"",
format_duration(duration)
));

Ok(())
Expand Down
58 changes: 43 additions & 15 deletions agdb_benchmarks/src/utilities.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,12 @@
use crate::bench_result::BenchResult;
use crate::CELL_PADDING;
use crate::LOCALE;
use crate::PADDING;
use num_format::ToFormattedString;
use std::io::Write;
use std::time::Duration;
use std::time::Instant;

pub(crate) fn measured(mut predicate: impl FnMut() -> BenchResult<()>) -> BenchResult<Duration> {
let start = Instant::now();
predicate()?;
let duration = start.elapsed();
Ok(duration)
}

pub(crate) fn print_flush(message: String) {
print!("{message}");
std::io::stdout().flush().unwrap();
}

pub(crate) fn format_duration(duration: Duration) -> String {
if duration.as_micros() < 1000 {
format!(
Expand All @@ -30,10 +20,10 @@ pub(crate) fn format_duration(duration: Duration) -> String {
}
}

const KB: u64 = 1024;
const MB: u64 = KB * 1024;

pub(crate) fn format_size(bytes: u64) -> String {
const KB: u64 = 1024;
const MB: u64 = KB * 1024;

if (10 * MB) < bytes {
format!("{} MB", (bytes / MB).to_formatted_string(&LOCALE))
} else if (KB) < bytes {
Expand All @@ -42,3 +32,41 @@ pub(crate) fn format_size(bytes: u64) -> String {
format!("{} b", bytes.to_formatted_string(&LOCALE))
}
}

pub(crate) fn measured(mut predicate: impl FnMut() -> BenchResult<()>) -> BenchResult<Duration> {
let start = Instant::now();
predicate()?;
let duration = start.elapsed();
Ok(duration)
}

pub(crate) fn print_flush(message: String) {
print!("{message}");
std::io::stdout().flush().unwrap();
}

pub(crate) fn print_header() {
println!(
"{:PADDING$} | {:CELL_PADDING$} | {:CELL_PADDING$} | {:CELL_PADDING$} | {:CELL_PADDING$} | {:CELL_PADDING$}",
"Description", "Count", "Min", "Avg", "Max", "Total"
);
}

pub(crate) fn report(description: &str, mut times: Vec<Duration>) {
let zero_time: Duration = Duration::default();

times.sort();

let min = times.first().unwrap_or(&zero_time);
let max = times.last().unwrap_or(&zero_time);
let total = times.iter().sum::<Duration>();
let avg = if times.is_empty() {
zero_time
} else {
total / times.len() as u32
};

println!("{:PADDING$} | {:CELL_PADDING$} | {:CELL_PADDING$} | {:CELL_PADDING$} | {:CELL_PADDING$} | {:CELL_PADDING$}",
description, times.len().to_formatted_string(&LOCALE), format_duration(*min), format_duration(avg), format_duration(*max), format_duration(total)
)
}
Loading