Skip to content

Commit

Permalink
Run and test benchmarks against C# as well (#1965)
Browse files Browse the repository at this point in the history
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
  • Loading branch information
RReverser and bfops authored Nov 15, 2024
1 parent 6dcb525 commit a7a1d36
Show file tree
Hide file tree
Showing 14 changed files with 216 additions and 132 deletions.
14 changes: 10 additions & 4 deletions .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ jobs:
# summary PR" step). otherwise, we can use a fully shallow checkout
fetch-depth: ${{ env.PR_NUMBER && 1 || 2 }}

- name: Install stable toolchain
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
Expand All @@ -85,6 +85,13 @@ jobs:
target: wasm32-unknown-unknown
override: true

- name: Install .NET toolchain
uses: actions/setup-dotnet@v3
with:
dotnet-version: "8.x"
env:
DOTNET_INSTALL_DIR: ~/.dotnet

- name: Build
working-directory: crates/bench/
run: |
Expand Down Expand Up @@ -114,7 +121,7 @@ jobs:
rm -rf .spacetime
cargo bench --bench generic -- --save-baseline "$BASELINE_NAME" "$BENCH_FILTER"
# sticker price benchmark
cargo bench --bench generic -- --save-baseline "$BASELINE_NAME" 'stdb_module/disk/update_bulk'
cargo bench --bench generic -- --save-baseline "$BASELINE_NAME" 'stdb_module/.*/disk/update_bulk'
cargo bench --bench special -- --save-baseline "$BASELINE_NAME"
cargo run --bin summarize pack "$BASELINE_NAME"
popd
Expand Down Expand Up @@ -192,7 +199,7 @@ jobs:
- name: Install valgrind & iai-callgrind-runner
run: |
apt-get update
apt-get install -y valgrind protobuf-compiler bash sudo curl gh
apt-get install -y valgrind protobuf-compiler bash sudo curl gh
cargo install --git https://github.com/clockworklabs/iai-callgrind.git --branch main iai-callgrind-runner
git config --global --add safe.directory /__w/SpacetimeDB/SpacetimeDB
Expand Down Expand Up @@ -343,4 +350,3 @@ jobs:
echo "Letting anybody touch our git repo, in order to avoid breaking other jobs"
echo "This is necessary because we are running as root inside a docker image"
chmod -R a+rw .
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ regex.workspace = true
rusqlite.workspace = true
serde.workspace = true
serde_json.workspace = true
serial_test.workspace = true
tempdir.workspace = true
tokio.workspace = true
tracing-subscriber.workspace = true
Expand Down
7 changes: 5 additions & 2 deletions crates/bench/benches/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use spacetimedb_bench::{
};
use spacetimedb_lib::sats::AlgebraicType;
use spacetimedb_primitives::ColId;
use spacetimedb_testing::modules::{Csharp, Rust};

#[global_allocator]
static GLOBAL: MiMalloc = MiMalloc;
Expand All @@ -23,11 +24,13 @@ lazy_static! {
fn criterion_benchmark(c: &mut Criterion) {
bench_suite::<sqlite::SQLite>(c, true).unwrap();
bench_suite::<spacetime_raw::SpacetimeRaw>(c, true).unwrap();
bench_suite::<spacetime_module::SpacetimeModule>(c, true).unwrap();
bench_suite::<spacetime_module::SpacetimeModule<Rust>>(c, true).unwrap();
bench_suite::<spacetime_module::SpacetimeModule<Csharp>>(c, true).unwrap();

bench_suite::<sqlite::SQLite>(c, false).unwrap();
bench_suite::<spacetime_raw::SpacetimeRaw>(c, false).unwrap();
bench_suite::<spacetime_module::SpacetimeModule>(c, false).unwrap();
bench_suite::<spacetime_module::SpacetimeModule<Rust>>(c, false).unwrap();
bench_suite::<spacetime_module::SpacetimeModule<Csharp>>(c, false).unwrap();
}

#[inline(never)]
Expand Down
23 changes: 15 additions & 8 deletions crates/bench/benches/special.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use criterion::async_executor::AsyncExecutor;
use criterion::{criterion_group, criterion_main, Criterion};
use criterion::{criterion_group, criterion_main, Criterion, SamplingMode};
use mimalloc::MiMalloc;
use spacetimedb_bench::{
database::BenchDatabase,
Expand All @@ -9,6 +9,7 @@ use spacetimedb_bench::{
use spacetimedb_lib::sats::{self, bsatn};
use spacetimedb_lib::{bsatn::ToBsatn as _, ProductValue};
use spacetimedb_schema::schema::TableSchema;
use spacetimedb_testing::modules::{Csharp, ModuleLanguage, Rust};
use std::sync::Arc;
use std::sync::OnceLock;

Expand All @@ -20,14 +21,19 @@ fn criterion_benchmark(c: &mut Criterion) {
serialize_benchmarks::<u32_u64_u64>(c);
serialize_benchmarks::<u64_u64_u32>(c);

let db = SpacetimeModule::build(true).unwrap();
custom_benchmarks::<Rust>(c);
custom_benchmarks::<Csharp>(c);
}

fn custom_benchmarks<L: ModuleLanguage>(c: &mut Criterion) {
let db = SpacetimeModule::<L>::build(true).unwrap();

custom_module_benchmarks(&db, c);
custom_db_benchmarks(&db, c);
}

fn custom_module_benchmarks(m: &SpacetimeModule, c: &mut Criterion) {
let mut group = c.benchmark_group("special/stdb_module");
fn custom_module_benchmarks<L: ModuleLanguage>(m: &SpacetimeModule<L>, c: &mut Criterion) {
let mut group = c.benchmark_group(format!("special/{}", SpacetimeModule::<L>::name()));

let args = sats::product!["0".repeat(65536).into_boxed_str()];
group.bench_function("large_arguments/64KiB", |b| {
Expand All @@ -44,10 +50,11 @@ fn custom_module_benchmarks(m: &SpacetimeModule, c: &mut Criterion) {
}
}

fn custom_db_benchmarks(m: &SpacetimeModule, c: &mut Criterion) {
let mut group = c.benchmark_group("special/db_game");
fn custom_db_benchmarks<L: ModuleLanguage>(m: &SpacetimeModule<L>, c: &mut Criterion) {
let mut group = c.benchmark_group(format!("special/db_game/{}", L::NAME));
// This bench take long, so adjust for it
group.sample_size(10);
group.sampling_mode(SamplingMode::Flat);

let init_db: OnceLock<()> = OnceLock::new();
for n in [10, 100] {
Expand All @@ -69,14 +76,14 @@ fn custom_db_benchmarks(m: &SpacetimeModule, c: &mut Criterion) {
}

let init_db: OnceLock<()> = OnceLock::new();
for n in [500, 5_000] {
for n in [10, 100] {
let args = sats::product![n];
group.bench_function(format!("ia_loop/load={n}"), |b| {
// Initialize outside the benchmark so the db is seed once, to avoid `unique` constraints violations
init_db.get_or_init(|| {
m.block_on(async {
m.module
.call_reducer_binary("init_game_ia_loop", &sats::product![5_000])
.call_reducer_binary("init_game_ia_loop", &sats::product![500])
.await
.unwrap();
})
Expand Down
2 changes: 1 addition & 1 deletion crates/bench/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::ResultBench;
///
/// Not all benchmarks have to go through this trait.
pub trait BenchDatabase: Sized {
fn name() -> &'static str;
fn name() -> String;

type TableId: Clone + 'static;

Expand Down
45 changes: 27 additions & 18 deletions crates/bench/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ mod tests {
sqlite::SQLite,
ResultBench,
};
use serial_test::serial;
use spacetimedb_testing::modules::{Csharp, Rust};
use std::{io, path::Path, sync::Once};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};

Expand Down Expand Up @@ -101,30 +103,37 @@ mod tests {
Ok(())
}

fn test_basic_invariants<DB: BenchDatabase>() -> ResultBench<()> {
basic_invariants::<DB, u32_u64_str>(IndexStrategy::Unique0, true)?;
basic_invariants::<DB, u32_u64_u64>(IndexStrategy::Unique0, true)?;
basic_invariants::<DB, u32_u64_str>(IndexStrategy::BTreeEachColumn, true)?;
basic_invariants::<DB, u32_u64_u64>(IndexStrategy::BTreeEachColumn, true)?;
Ok(())
}

#[test]
fn test_basic_invariants_sqlite() {
basic_invariants::<SQLite, u32_u64_str>(IndexStrategy::Unique0, true).unwrap();
basic_invariants::<SQLite, u32_u64_u64>(IndexStrategy::Unique0, true).unwrap();
basic_invariants::<SQLite, u32_u64_str>(IndexStrategy::BTreeEachColumn, true).unwrap();
basic_invariants::<SQLite, u32_u64_u64>(IndexStrategy::BTreeEachColumn, true).unwrap();
fn test_basic_invariants_sqlite() -> ResultBench<()> {
test_basic_invariants::<SQLite>()
}

#[test]
fn test_basic_invariants_spacetime_raw() {
basic_invariants::<SpacetimeRaw, u32_u64_str>(IndexStrategy::Unique0, true).unwrap();
basic_invariants::<SpacetimeRaw, u32_u64_u64>(IndexStrategy::Unique0, true).unwrap();
basic_invariants::<SpacetimeRaw, u32_u64_str>(IndexStrategy::BTreeEachColumn, true).unwrap();
basic_invariants::<SpacetimeRaw, u32_u64_u64>(IndexStrategy::BTreeEachColumn, true).unwrap();
fn test_basic_invariants_spacetime_raw() -> ResultBench<()> {
test_basic_invariants::<SpacetimeRaw>()
}

// note: there can only be one #[test] invoking spacetime module stuff.
// #[test]s run concurrently and they fight over lockfiles.
// so, run the sub-tests here in sequence.

#[test]
#[serial]
fn test_basic_invariants_spacetime_module_rust() -> ResultBench<()> {
test_basic_invariants::<SpacetimeModule<Rust>>()
}

#[test]
fn test_basic_invariants_spacetime_module() {
// note: there can only be one #[test] invoking spacetime module stuff.
// #[test]s run concurrently and they fight over lockfiles.
// so, run the sub-tests here in sequence.
basic_invariants::<SpacetimeModule, u32_u64_str>(IndexStrategy::Unique0, true).unwrap();
basic_invariants::<SpacetimeModule, u32_u64_u64>(IndexStrategy::Unique0, true).unwrap();
basic_invariants::<SpacetimeModule, u32_u64_str>(IndexStrategy::BTreeEachColumn, true).unwrap();
basic_invariants::<SpacetimeModule, u32_u64_u64>(IndexStrategy::BTreeEachColumn, true).unwrap();
#[serial]
fn test_basic_invariants_spacetime_module_csharp() -> ResultBench<()> {
test_basic_invariants::<SpacetimeModule<Csharp>>()
}
}
54 changes: 21 additions & 33 deletions crates/bench/src/spacetime_module.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::path::Path;
use std::{marker::PhantomData, path::Path};

use spacetimedb::db::{Config, Storage};
use spacetimedb_lib::{
Expand All @@ -7,7 +7,7 @@ use spacetimedb_lib::{
};
use spacetimedb_paths::RootDir;
use spacetimedb_primitives::ColId;
use spacetimedb_testing::modules::{start_runtime, CompilationMode, CompiledModule, LoggerRecord, ModuleHandle};
use spacetimedb_testing::modules::{start_runtime, LoggerRecord, ModuleHandle, ModuleLanguage};
use tokio::runtime::Runtime;

use crate::{
Expand All @@ -17,23 +17,6 @@ use crate::{
};
use criterion::async_executor::AsyncExecutor;

lazy_static::lazy_static! {
pub static ref BENCHMARKS_MODULE: CompiledModule = {
if std::env::var_os("STDB_BENCH_CS").is_some() {
CompiledModule::compile("benchmarks-cs", CompilationMode::Release)
} else {
// Temporarily add CARGO_TARGET_DIR override to avoid conflicts with main target dir.
// Otherwise for some reason Cargo will mark all dependencies with build scripts as
// fresh - but only if running benchmarks (if modules are built in release mode).
// See https://github.com/clockworklabs/SpacetimeDB/issues/401.
std::env::set_var("CARGO_TARGET_DIR", concat!(env!("CARGO_MANIFEST_DIR"), "/target"));
let module = CompiledModule::compile("benchmarks", CompilationMode::Release);
std::env::remove_var("CARGO_TARGET_DIR");
module
}
};
}

/// A benchmark backend that invokes a spacetime module.
///
/// This is tightly tied to the file `modules/benchmarks/src/lib.rs`;
Expand All @@ -42,26 +25,27 @@ lazy_static::lazy_static! {
///
/// See the doc comment there for information on the formatting expected for
/// table and reducer names.
pub struct SpacetimeModule {
pub struct SpacetimeModule<L> {
// Module must be dropped BEFORE runtime otherwise there is a deadlock!
// In Rust, struct fields are guaranteed to drop in declaration order, so don't reorder this field.
pub module: ModuleHandle,
runtime: Runtime,
lang: PhantomData<L>,
}

// Note: we use block_on for the methods here. It adds about 70ns of overhead.
// This isn't currently a problem. Overhead to call an empty reducer is currently 20_000 ns.

impl AsyncExecutor for &SpacetimeModule {
impl<L> AsyncExecutor for &SpacetimeModule<L> {
fn block_on<T>(&self, future: impl std::future::Future<Output = T>) -> T {
self.runtime.block_on(future)
}
}

// It's easier to do it this way because async traits are a mess.
impl BenchDatabase for SpacetimeModule {
fn name() -> &'static str {
"stdb_module"
impl<L: ModuleLanguage> BenchDatabase for SpacetimeModule<L> {
fn name() -> String {
format!("stdb_module/{}", L::NAME)
}

type TableId = TableId;
Expand All @@ -81,7 +65,7 @@ impl BenchDatabase for SpacetimeModule {
// It's fine that we're constructing this path ad-hoc, as it's just
// a path location for tests, not part of our stable directory structure.
let path = RootDir(Path::new(env!("CARGO_MANIFEST_DIR")).join(".spacetime"));
BENCHMARKS_MODULE.load_module(config, Some(&path)).await
L::get_module().load_module(config, Some(&path)).await
});

for table in module.client.module.info.module_def.tables() {
Expand All @@ -90,7 +74,11 @@ impl BenchDatabase for SpacetimeModule {
for reducer in module.client.module.info.module_def.reducers() {
log::trace!("SPACETIME_MODULE: LOADED REDUCER: {:?}", reducer);
}
Ok(SpacetimeModule { runtime, module })
Ok(SpacetimeModule {
runtime,
module,
lang: PhantomData,
})
}

fn create_table<T: BenchTable>(
Expand All @@ -105,7 +93,7 @@ impl BenchDatabase for SpacetimeModule {
}

fn clear_table(&mut self, table_id: &Self::TableId) -> ResultBench<()> {
let SpacetimeModule { runtime, module } = self;
let SpacetimeModule { runtime, module, .. } = self;
runtime.block_on(async move {
// FIXME: this doesn't work. delete is unimplemented!!
/*
Expand All @@ -122,7 +110,7 @@ impl BenchDatabase for SpacetimeModule {
// message in the log.
// This implementation will not work if other people are concurrently interacting with our module.
fn count_table(&mut self, table_id: &Self::TableId) -> ResultBench<u32> {
let SpacetimeModule { runtime, module } = self;
let SpacetimeModule { runtime, module, .. } = self;

let count = runtime.block_on(async move {
let name = format!("count_{}", table_id.snake_case);
Expand All @@ -140,7 +128,7 @@ impl BenchDatabase for SpacetimeModule {
}

fn empty_transaction(&mut self) -> ResultBench<()> {
let SpacetimeModule { runtime, module } = self;
let SpacetimeModule { runtime, module, .. } = self;

runtime.block_on(async move {
module.call_reducer_binary("empty", &[].into()).await?;
Expand All @@ -151,7 +139,7 @@ impl BenchDatabase for SpacetimeModule {
fn insert_bulk<T: BenchTable>(&mut self, table_id: &Self::TableId, rows: Vec<T>) -> ResultBench<()> {
let rows = rows.into_iter().map(|row| row.into_product_value()).collect();
let args = product![ArrayValue::Product(rows)];
let SpacetimeModule { runtime, module } = self;
let SpacetimeModule { runtime, module, .. } = self;
let reducer_name = format!("insert_bulk_{}", table_id.snake_case);

runtime.block_on(async move {
Expand All @@ -162,7 +150,7 @@ impl BenchDatabase for SpacetimeModule {

fn update_bulk<T: BenchTable>(&mut self, table_id: &Self::TableId, row_count: u32) -> ResultBench<()> {
let args = product![row_count];
let SpacetimeModule { runtime, module } = self;
let SpacetimeModule { runtime, module, .. } = self;
let reducer_name = format!("update_bulk_{}", table_id.snake_case);

runtime.block_on(async move {
Expand All @@ -172,7 +160,7 @@ impl BenchDatabase for SpacetimeModule {
}

fn iterate(&mut self, table_id: &Self::TableId) -> ResultBench<()> {
let SpacetimeModule { runtime, module } = self;
let SpacetimeModule { runtime, module, .. } = self;
let reducer_name = format!("iterate_{}", table_id.snake_case);

runtime.block_on(async move {
Expand All @@ -187,7 +175,7 @@ impl BenchDatabase for SpacetimeModule {
col_id: impl Into<ColId>,
value: AlgebraicValue,
) -> ResultBench<()> {
let SpacetimeModule { runtime, module } = self;
let SpacetimeModule { runtime, module, .. } = self;

let product_type = T::product_type();
let column_name = product_type.elements[col_id.into().idx()].name.as_ref().unwrap();
Expand Down
4 changes: 2 additions & 2 deletions crates/bench/src/spacetime_raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ pub struct SpacetimeRaw {
}

impl BenchDatabase for SpacetimeRaw {
fn name() -> &'static str {
"stdb_raw"
fn name() -> String {
"stdb_raw".to_owned()
}
type TableId = TableId;

Expand Down
Loading

2 comments on commit a7a1d36

@github-actions
Copy link

@github-actions github-actions bot commented on a7a1d36 Nov 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmarking failed. Please check the workflow run for details.

@github-actions
Copy link

@github-actions github-actions bot commented on a7a1d36 Nov 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Callgrind benchmark results

Callgrind Benchmark Report

These benchmarks were run using callgrind,
an instruction-level profiler. They allow comparisons between sqlite (sqlite), SpacetimeDB running through a module (stdb_module), and the underlying SpacetimeDB data storage engine (stdb_raw). Callgrind emulates a CPU to collect the below estimates.

Measurement changes larger than five percent are in bold.

In-memory benchmarks

callgrind: empty transaction

db total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw 6397 6397 0.00% 6481 6497 -0.25%
sqlite 5579 5589 -0.18% 6009 6007 0.03%

callgrind: filter

db schema indices count preload _column data_type total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str no_index 64 128 1 u64 76592 76592 0.00% 77076 77064 0.02%
stdb_raw u32_u64_str no_index 64 128 2 string 119923 118834 0.92% 120687 119656 0.86%
stdb_raw u32_u64_str btree_each_column 64 128 2 string 25082 25081 0.00% 25678 25775 -0.38%
stdb_raw u32_u64_str btree_each_column 64 128 1 u64 24049 24049 0.00% 24445 24561 -0.47%
sqlite u32_u64_str no_index 64 128 2 string 144695 144695 0.00% 146125 146231 -0.07%
sqlite u32_u64_str no_index 64 128 1 u64 124044 124044 0.00% 125186 125334 -0.12%
sqlite u32_u64_str btree_each_column 64 128 1 u64 131361 131361 0.00% 132819 132787 0.02%
sqlite u32_u64_str btree_each_column 64 128 2 string 134494 134494 0.00% 136096 136218 -0.09%

callgrind: insert bulk

db schema indices count preload total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 64 128 870940 872061 -0.13% 890532 920721 -3.28%
stdb_raw u32_u64_str btree_each_column 64 128 1021063 1019308 0.17% 1080211 1079858 0.03%
sqlite u32_u64_str unique_0 64 128 398336 398320 0.00% 416760 413936 0.68%
sqlite u32_u64_str btree_each_column 64 128 983637 983637 0.00% 1026403 1020715 0.56%

callgrind: iterate

db schema indices count total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 1024 153724 153721 0.00% 153838 153849 -0.01%
stdb_raw u32_u64_str unique_0 64 16749 16746 0.02% 16847 16842 0.03%
sqlite u32_u64_str unique_0 1024 1068275 1067255 0.10% 1071621 1070715 0.08%
sqlite u32_u64_str unique_0 64 76279 76201 0.10% 77387 77255 0.17%

callgrind: serialize_product_value

count format total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
64 json 47528 47528 0.00% 50214 50214 0.00%
64 bsatn 25509 25509 0.00% 27821 27787 0.12%
16 bsatn 8200 8200 0.00% 9628 9594 0.35%
16 json 12188 12188 0.00% 14126 14126 0.00%

callgrind: update bulk

db schema indices count preload total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 1024 1024 20388882 19983993 2.03% 21068940 20438773 3.08%
stdb_raw u32_u64_str unique_0 64 128 1277818 1277965 -0.01% 1350966 1343877 0.53%
sqlite u32_u64_str unique_0 1024 1024 1802188 1802182 0.00% 1811458 1811438 0.00%
sqlite u32_u64_str unique_0 64 128 128534 128528 0.00% 131522 131340 0.14%
On-disk benchmarks

callgrind: empty transaction

db total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw 6402 6402 0.00% 6498 6498 0.00%
sqlite 5621 5621 0.00% 6111 6069 0.69%

callgrind: filter

db schema indices count preload _column data_type total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str no_index 64 128 1 u64 76597 76597 0.00% 77081 77049 0.04%
stdb_raw u32_u64_str no_index 64 128 2 string 118839 118860 -0.02% 119567 119646 -0.07%
stdb_raw u32_u64_str btree_each_column 64 128 2 string 25087 25086 0.00% 25639 25744 -0.41%
stdb_raw u32_u64_str btree_each_column 64 128 1 u64 24054 24054 0.00% 24446 24506 -0.24%
sqlite u32_u64_str no_index 64 128 1 u64 125965 125965 0.00% 127491 127555 -0.05%
sqlite u32_u64_str no_index 64 128 2 string 146616 146616 0.00% 148414 148404 0.01%
sqlite u32_u64_str btree_each_column 64 128 2 string 136616 136616 0.00% 138696 138654 0.03%
sqlite u32_u64_str btree_each_column 64 128 1 u64 133457 133457 0.00% 135369 135237 0.10%

callgrind: insert bulk

db schema indices count preload total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 64 128 821854 821628 0.03% 871536 869146 0.27%
stdb_raw u32_u64_str btree_each_column 64 128 970546 969047 0.15% 1028860 1027657 0.12%
sqlite u32_u64_str unique_0 64 128 415857 415863 -0.00% 433417 430645 0.64%
sqlite u32_u64_str btree_each_column 64 128 1021908 1021898 0.00% 1063426 1058636 0.45%

callgrind: iterate

db schema indices count total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 1024 153729 153726 0.00% 153827 153842 -0.01%
stdb_raw u32_u64_str unique_0 64 16754 16751 0.02% 16852 16847 0.03%
sqlite u32_u64_str unique_0 1024 1071343 1070323 0.10% 1075087 1074165 0.09%
sqlite u32_u64_str unique_0 64 78033 77973 0.08% 79393 79295 0.12%

callgrind: serialize_product_value

count format total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
64 json 47528 47528 0.00% 50214 50214 0.00%
64 bsatn 25509 25509 0.00% 27821 27787 0.12%
16 bsatn 8200 8200 0.00% 9628 9594 0.35%
16 json 12188 12188 0.00% 14126 14126 0.00%

callgrind: update bulk

db schema indices count preload total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 1024 1024 18899226 18903887 -0.02% 19603906 19440567 0.84%
stdb_raw u32_u64_str unique_0 64 128 1231074 1231460 -0.03% 1306392 1295388 0.85%
sqlite u32_u64_str unique_0 1024 1024 1809743 1809743 0.00% 1818455 1818307 0.01%
sqlite u32_u64_str unique_0 64 128 132654 132654 0.00% 135628 135574 0.04%

Please sign in to comment.