Skip to content

Commit

Permalink
refactor: Add TableId to relvar type (#1803)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshua-spacetime authored Oct 11, 2024
1 parent b1b58ac commit df5b78a
Show file tree
Hide file tree
Showing 18 changed files with 823 additions and 532 deletions.
30 changes: 15 additions & 15 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ members = [
"crates/core",
"crates/data-structures",
"crates/durability",
"crates/expr",
"crates/fs-utils",
"crates/lib",
"crates/planner",
"crates/metrics",
"crates/primitives",
"crates/sats",
Expand Down Expand Up @@ -96,10 +96,10 @@ spacetimedb-commitlog = { path = "crates/commitlog", version = "1.0.0-rc1" }
spacetimedb-core = { path = "crates/core", version = "1.0.0-rc1" }
spacetimedb-data-structures = { path = "crates/data-structures", version = "1.0.0-rc1" }
spacetimedb-durability = { path = "crates/durability", version = "1.0.0-rc1" }
spacetimedb-expr = { path = "crates/expr", version = "1.0.0-rc1" }
spacetimedb-lib = { path = "crates/lib", default-features = false, version = "1.0.0-rc1" }
spacetimedb-metrics = { path = "crates/metrics", version = "1.0.0-rc1" }
spacetimedb-primitives = { path = "crates/primitives", version = "1.0.0-rc1" }
spacetimedb-query-planner = { path = "crates/planner", version = "1.0.0-rc1" }
spacetimedb-sats = { path = "crates/sats", version = "1.0.0-rc1" }
spacetimedb-schema = { path = "crates/schema", version = "1.0.0-rc1" }
spacetimedb-standalone = { path = "crates/standalone", version = "1.0.0-rc1" }
Expand Down
2 changes: 1 addition & 1 deletion crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ spacetimedb-schema.workspace = true
spacetimedb-table.workspace = true
spacetimedb-vm.workspace = true
spacetimedb-snapshot.workspace = true
spacetimedb-query-planner.workspace = true
spacetimedb-expr.workspace = true

anyhow = { workspace = true, features = ["backtrace"] }
arrayvec.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::path::PathBuf;
use std::sync::{MutexGuard, PoisonError};

use hex::FromHexError;
use spacetimedb_query_planner::logical::errors::TypingError;
use spacetimedb_expr::errors::TypingError;
use spacetimedb_sats::AlgebraicType;
use spacetimedb_schema::error::ValidationErrors;
use spacetimedb_snapshot::SnapshotError;
Expand Down
6 changes: 3 additions & 3 deletions crates/core/src/sql/ast.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::db::relational_db::{MutTx, RelationalDB, Tx};
use crate::error::{DBError, PlanError};
use spacetimedb_data_structures::map::{HashCollectionExt as _, IntMap};
use spacetimedb_expr::check::SchemaView;
use spacetimedb_expr::statement::parse_and_type_sql;
use spacetimedb_lib::db::auth::StAccess;
use spacetimedb_lib::db::error::RelationError;
use spacetimedb_lib::identity::AuthCtx;
use spacetimedb_lib::relation::{ColExpr, FieldName};
use spacetimedb_primitives::ColId;
use spacetimedb_query_planner::logical::bind::SchemaView;
use spacetimedb_query_planner::logical::stmt::parse_and_type_sql;
use spacetimedb_sats::{AlgebraicType, AlgebraicValue};
use spacetimedb_schema::schema::{ColumnSchema, TableSchema};
use spacetimedb_vm::errors::ErrorVm;
Expand Down Expand Up @@ -480,7 +480,7 @@ pub struct SchemaViewer<'a, T> {
}

impl<T: TableSchemaView> SchemaView for SchemaViewer<'_, T> {
fn schema(&self, name: &str, _: bool) -> Option<Arc<TableSchema>> {
fn schema(&self, name: &str) -> Option<Arc<TableSchema>> {
let name = name.to_owned().into_boxed_str();
let schema = self
.tx
Expand Down
11 changes: 8 additions & 3 deletions crates/core/src/subscription/module_subscription_actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ use crate::vm::check_row_limit;
use crate::worker_metrics::WORKER_METRICS;
use parking_lot::RwLock;
use spacetimedb_client_api_messages::websocket::FormatSwitch;
use spacetimedb_expr::check::parse_and_type_sub;
use spacetimedb_expr::ty::TyCtx;
use spacetimedb_lib::identity::AuthCtx;
use spacetimedb_lib::Identity;
use spacetimedb_query_planner::logical::bind::parse_and_type_sub;
use spacetimedb_vm::errors::ErrorVm;
use spacetimedb_vm::expr::AuthAccess;
use std::time::Duration;
Expand Down Expand Up @@ -88,7 +89,11 @@ impl ModuleSubscriptions {
} else {
// NOTE: The following ensures compliance with the 1.0 sql api.
// Come 1.0, it will have replaced the current compilation stack.
parse_and_type_sub(sql, &SchemaViewer::new(&self.relational_db, &*tx, &auth))?;
parse_and_type_sub(
&mut TyCtx::default(),
sql,
&SchemaViewer::new(&self.relational_db, &*tx, &auth),
)?;

let mut compiled = compile_read_only_query(&self.relational_db, &auth, &tx, sql)?;
// Note that no error path is needed here.
Expand Down Expand Up @@ -249,9 +254,9 @@ mod tests {
use crate::error::DBError;
use crate::execution_context::ExecutionContext;
use spacetimedb_client_api_messages::websocket::Subscribe;
use spacetimedb_expr::errors::{TypingError, Unresolved};
use spacetimedb_lib::db::auth::StAccess;
use spacetimedb_lib::{error::ResultTest, AlgebraicType, Identity};
use spacetimedb_query_planner::logical::errors::{TypingError, Unresolved};
use spacetimedb_sats::product;
use std::time::Instant;
use std::{sync::Arc, time::Duration};
Expand Down
4 changes: 3 additions & 1 deletion crates/planner/Cargo.toml → crates/expr/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
[package]
name = "spacetimedb-query-planner"
name = "spacetimedb-expr"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license-file = "LICENSE"
description = "The logical expression representation for the SpacetimeDB query engine"

[dependencies]
derive_more.workspace = true
Expand Down
File renamed without changes.
63 changes: 34 additions & 29 deletions crates/planner/src/logical/bind.rs → crates/expr/src/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,26 @@ use spacetimedb_sql_parser::{
ast::{
self,
sub::{SqlAst, SqlSelect},
SqlFrom,
SqlFrom, SqlIdent, SqlJoin,
},
parser::sub::parse_subscription,
};

use crate::ty::TyId;

use super::{
assert_eq_types,
errors::{DuplicateName, TypingError, Unresolved, Unsupported},
expr::{Expr, Let, RelExpr},
ty::{Symbol, TyCtx, TyEnv, TyId, Type},
ty::{Symbol, TyCtx, TyEnv},
type_expr, type_proj, type_select,
};

/// The result of type checking and name resolution
pub type TypingResult<T> = core::result::Result<T, TypingError>;

pub trait SchemaView {
fn schema(&self, name: &str, case_sensitive: bool) -> Option<Arc<TableSchema>>;
fn schema(&self, name: &str) -> Option<Arc<TableSchema>>;
}

pub trait TypeChecker {
Expand All @@ -40,12 +42,12 @@ pub trait TypeChecker {
) -> TypingResult<(RelExpr, Option<Symbol>)> {
match from {
SqlFrom::Expr(expr, None) => Self::type_rel(ctx, expr, tx),
SqlFrom::Expr(expr, Some(alias)) => {
SqlFrom::Expr(expr, Some(SqlIdent(alias))) => {
let (expr, _) = Self::type_rel(ctx, expr, tx)?;
let symbol = ctx.gen_symbol(alias.name);
let symbol = ctx.gen_symbol(alias);
Ok((expr, Some(symbol)))
}
SqlFrom::Join(r, alias, joins) => {
SqlFrom::Join(r, SqlIdent(alias), joins) => {
// The type environment with which to type the join expressions
let mut env = TyEnv::default();
// The lowered inputs to the join operator
Expand All @@ -57,33 +59,37 @@ pub trait TypeChecker {

let input = Self::type_rel(ctx, r, tx)?.0;
let ty = input.ty_id();
let name = ctx.gen_symbol(alias.name);
let name = ctx.gen_symbol(alias);

env.add(name, ty);
inputs.push(input);
types.push((name, ty));

for join in joins {
let input = Self::type_rel(ctx, join.expr, tx)?.0;
for SqlJoin {
expr,
alias: SqlIdent(alias),
on,
} in joins
{
let input = Self::type_rel(ctx, expr, tx)?.0;
let ty = input.ty_id();
let name = ctx.gen_symbol(&join.alias.name);
let name = ctx.gen_symbol(&alias);

// New join variable is now in scope
if env.add(name, ty).is_some() {
return Err(DuplicateName(join.alias.name).into());
return Err(DuplicateName(alias.into_string()).into());
}

inputs.push(input);
types.push((name, ty));

// Type check join expression with current type environment
if let Some(on) = join.on {
if let Some(on) = on {
exprs.push(type_expr(ctx, &env, on, Some(TyId::BOOL))?);
}
}

let ty = Type::Row(types.clone().into_boxed_slice());
let ty = ctx.add(ty);
let ty = ctx.add_row_type(types.clone());
let input = RelExpr::Join(inputs.into(), ty);
let vars = types
.into_iter()
Expand All @@ -101,21 +107,19 @@ pub trait TypeChecker {
tx: &impl SchemaView,
) -> TypingResult<(RelExpr, Option<Symbol>)> {
match expr {
ast::RelExpr::Var(var) => {
ast::RelExpr::Var(SqlIdent(var)) => {
let schema = tx
.schema(&var.name, var.case_sensitive)
.ok_or_else(|| Unresolved::table(&var.name))
.schema(&var)
.ok_or_else(|| Unresolved::table(&var))
.map_err(TypingError::from)?;
let mut types = Vec::new();
for ColumnSchema { col_name, col_type, .. } in schema.columns() {
let ty = Type::Alg(col_type.clone());
let id = ctx.add(ty);
let id = ctx.add_algebraic_type(col_type);
let name = ctx.gen_symbol(col_name);
types.push((name, id));
}
let ty = Type::Var(types.into_boxed_slice());
let id = ctx.add(ty);
let symbol = ctx.gen_symbol(var.name);
let id = ctx.add_var_type(schema.table_id, types);
let symbol = ctx.gen_symbol(var);
Ok((RelExpr::RelVar(schema, id), Some(symbol)))
}
ast::RelExpr::Ast(ast) => Ok((Self::type_ast(ctx, *ast, tx)?, None)),
Expand Down Expand Up @@ -170,10 +174,9 @@ impl TypeChecker for SubChecker {
}

/// Parse and type check a subscription query
pub fn parse_and_type_sub(sql: &str, tx: &impl SchemaView) -> TypingResult<RelExpr> {
let mut ctx = TyCtx::default();
let expr = SubChecker::type_ast(&mut ctx, parse_subscription(sql)?, tx)?;
expect_table_type(&ctx, expr)
pub fn parse_and_type_sub(ctx: &mut TyCtx, sql: &str, tx: &impl SchemaView) -> TypingResult<RelExpr> {
let expr = SubChecker::type_ast(ctx, parse_subscription(sql)?, tx)?;
expect_table_type(ctx, expr)
}

/// Returns an error if the input type is not a table type or relvar
Expand All @@ -192,6 +195,8 @@ mod tests {
};
use std::sync::Arc;

use crate::ty::TyCtx;

use super::{parse_and_type_sub, SchemaView};

fn module_def() -> ModuleDef {
Expand Down Expand Up @@ -222,7 +227,7 @@ mod tests {
struct SchemaViewer(ModuleDef);

impl SchemaView for SchemaViewer {
fn schema(&self, name: &str, _: bool) -> Option<Arc<TableSchema>> {
fn schema(&self, name: &str) -> Option<Arc<TableSchema>> {
self.0.table(name).map(|def| {
Arc::new(TableSchema::from_module_def(
&self.0,
Expand Down Expand Up @@ -253,7 +258,7 @@ mod tests {
"select * from (select t.* from t join (select u32 as a from s) s on t.u32 = s.a)",
"select * from (select * from t union all select * from t)",
] {
let result = parse_and_type_sub(sql, &tx);
let result = parse_and_type_sub(&mut TyCtx::default(), sql, &tx);
assert!(result.is_ok());
}
}
Expand Down Expand Up @@ -294,7 +299,7 @@ mod tests {
// Union arguments are of different types
"select * from (select * from t union all select * from s)",
] {
let result = parse_and_type_sub(sql, &tx);
let result = parse_and_type_sub(&mut TyCtx::default(), sql, &tx);
assert!(result.is_err());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use spacetimedb_sql_parser::{ast::BinOp, parser::errors::SqlParseError};
use thiserror::Error;

use super::{
stmt::InvalidVar,
statement::InvalidVar,
ty::{InvalidTypeId, TypeWithCtx},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,8 @@ impl Expr {
}

/// Returns a string literal
pub fn str(v: String) -> Self {
let s = v.into_boxed_str();
Self::Lit(AlgebraicValue::String(s), TyId::STR)
pub fn str(v: Box<str>) -> Self {
Self::Lit(AlgebraicValue::String(v), TyId::STR)
}

/// The type id of this expression
Expand Down
Loading

2 comments on commit df5b78a

@github-actions
Copy link

@github-actions github-actions bot commented on df5b78a Oct 11, 2024

Choose a reason for hiding this comment

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

Criterion benchmark results

Criterion benchmark report

YOU SHOULD PROBABLY IGNORE THESE RESULTS.

Criterion is a wall time based benchmarking system that is extremely noisy when run on CI. We collect these results for longitudinal analysis, but they are not reliable for comparing individual PRs.

Go look at the callgrind report instead.

empty

db on disk new latency old latency new throughput old throughput
sqlite 💿 421.3±1.67ns 412.6±1.96ns - -
sqlite 🧠 411.5±1.51ns 404.1±2.46ns - -
stdb_raw 💿 626.1±1.00ns 622.8±2.95ns - -
stdb_raw 🧠 625.9±1.13ns 623.2±1.10ns - -

insert_1

db on disk schema indices preload new latency old latency new throughput old throughput

insert_bulk

db on disk schema indices preload count new latency old latency new throughput old throughput
sqlite 💿 u32_u64_str btree_each_column 2048 256 586.5±1.68µs 585.0±0.72µs 1705 tx/sec 1709 tx/sec
sqlite 💿 u32_u64_str unique_0 2048 256 158.1±10.95µs 152.2±7.86µs 6.2 Ktx/sec 6.4 Ktx/sec
sqlite 💿 u32_u64_u64 btree_each_column 2048 256 470.4±0.62µs 464.1±0.47µs 2.1 Ktx/sec 2.1 Ktx/sec
sqlite 💿 u32_u64_u64 unique_0 2048 256 139.9±0.73µs 134.1±0.61µs 7.0 Ktx/sec 7.3 Ktx/sec
sqlite 🧠 u32_u64_str btree_each_column 2048 256 446.2±0.45µs 450.1±0.74µs 2.2 Ktx/sec 2.2 Ktx/sec
sqlite 🧠 u32_u64_str unique_0 2048 256 123.8±0.84µs 120.1±0.35µs 7.9 Ktx/sec 8.1 Ktx/sec
sqlite 🧠 u32_u64_u64 btree_each_column 2048 256 370.9±0.84µs 364.2±0.26µs 2.6 Ktx/sec 2.7 Ktx/sec
sqlite 🧠 u32_u64_u64 unique_0 2048 256 106.9±0.59µs 101.1±0.25µs 9.1 Ktx/sec 9.7 Ktx/sec
stdb_raw 💿 u32_u64_str btree_each_column 2048 256 644.1±16.20µs 512.1±17.19µs 1552 tx/sec 1952 tx/sec
stdb_raw 💿 u32_u64_str unique_0 2048 256 497.0±19.12µs 493.1±25.97µs 2011 tx/sec 2027 tx/sec
stdb_raw 💿 u32_u64_u64 btree_each_column 2048 256 381.0±6.51µs 338.5±4.61µs 2.6 Ktx/sec 2.9 Ktx/sec
stdb_raw 💿 u32_u64_u64 unique_0 2048 256 348.7±10.99µs 315.6±4.78µs 2.8 Ktx/sec 3.1 Ktx/sec
stdb_raw 🧠 u32_u64_str btree_each_column 2048 256 308.6±0.29µs 308.4±0.27µs 3.2 Ktx/sec 3.2 Ktx/sec
stdb_raw 🧠 u32_u64_str unique_0 2048 256 242.4±0.33µs 240.4±0.35µs 4.0 Ktx/sec 4.1 Ktx/sec
stdb_raw 🧠 u32_u64_u64 btree_each_column 2048 256 247.0±0.10µs 247.7±0.17µs 4.0 Ktx/sec 3.9 Ktx/sec
stdb_raw 🧠 u32_u64_u64 unique_0 2048 256 222.0±0.18µs 222.2±0.11µs 4.4 Ktx/sec 4.4 Ktx/sec

iterate

db on disk schema indices new latency old latency new throughput old throughput
sqlite 💿 u32_u64_str unique_0 21.8±0.06µs 23.5±0.15µs 44.7 Ktx/sec 41.5 Ktx/sec
sqlite 💿 u32_u64_u64 unique_0 19.4±0.15µs 21.9±0.04µs 50.3 Ktx/sec 44.5 Ktx/sec
sqlite 🧠 u32_u64_str unique_0 19.3±0.23µs 20.5±0.18µs 50.6 Ktx/sec 47.6 Ktx/sec
sqlite 🧠 u32_u64_u64 unique_0 17.0±0.09µs 19.2±0.05µs 57.3 Ktx/sec 50.8 Ktx/sec
stdb_raw 💿 u32_u64_str unique_0 4.0±0.00µs 4.8±0.00µs 246.6 Ktx/sec 205.2 Ktx/sec
stdb_raw 💿 u32_u64_u64 unique_0 3.9±0.00µs 4.6±0.00µs 253.0 Ktx/sec 210.3 Ktx/sec
stdb_raw 🧠 u32_u64_str unique_0 4.0±0.00µs 4.8±0.00µs 246.8 Ktx/sec 205.6 Ktx/sec
stdb_raw 🧠 u32_u64_u64 unique_0 3.9±0.00µs 4.6±0.00µs 253.0 Ktx/sec 210.4 Ktx/sec

find_unique

db on disk key type preload new latency old latency new throughput old throughput

filter

db on disk key type index strategy load count new latency old latency new throughput old throughput
sqlite 💿 string index 2048 256 67.5±0.20µs 68.5±0.23µs 14.5 Ktx/sec 14.2 Ktx/sec
sqlite 💿 u64 index 2048 256 62.0±0.17µs 66.3±0.17µs 15.7 Ktx/sec 14.7 Ktx/sec
sqlite 🧠 string index 2048 256 63.3±0.19µs 65.4±0.22µs 15.4 Ktx/sec 14.9 Ktx/sec
sqlite 🧠 u64 index 2048 256 57.3±0.11µs 60.0±0.17µs 17.0 Ktx/sec 16.3 Ktx/sec
stdb_raw 💿 string index 2048 256 4.9±0.00µs 4.9±0.00µs 198.8 Ktx/sec 198.8 Ktx/sec
stdb_raw 💿 u64 index 2048 256 4.8±0.00µs 4.8±0.00µs 205.0 Ktx/sec 204.9 Ktx/sec
stdb_raw 🧠 string index 2048 256 4.9±0.00µs 4.9±0.00µs 198.8 Ktx/sec 198.8 Ktx/sec
stdb_raw 🧠 u64 index 2048 256 4.8±0.00µs 4.8±0.00µs 205.2 Ktx/sec 204.8 Ktx/sec

serialize

schema format count new latency old latency new throughput old throughput
u32_u64_str bflatn_to_bsatn_fast_path 100 3.3±0.01µs 3.3±0.01µs 29.2 Mtx/sec 29.2 Mtx/sec
u32_u64_str bflatn_to_bsatn_slow_path 100 3.4±0.01µs 3.4±0.00µs 28.3 Mtx/sec 27.8 Mtx/sec
u32_u64_str bsatn 100 2.4±0.02µs 2.3±0.02µs 40.2 Mtx/sec 40.9 Mtx/sec
u32_u64_str bsatn 100 40.5±0.09ns 40.5±0.12ns 2.3 Gtx/sec 2.3 Gtx/sec
u32_u64_str json 100 5.1±0.06µs 4.9±0.02µs 18.9 Mtx/sec 19.6 Mtx/sec
u32_u64_str json 100 8.5±0.05µs 8.1±0.04µs 11.2 Mtx/sec 11.8 Mtx/sec
u32_u64_str product_value 100 1014.8±0.62ns 1017.6±0.63ns 94.0 Mtx/sec 93.7 Mtx/sec
u32_u64_u64 bflatn_to_bsatn_fast_path 100 1101.0±12.16ns 1113.9±10.69ns 86.6 Mtx/sec 85.6 Mtx/sec
u32_u64_u64 bflatn_to_bsatn_slow_path 100 2.8±0.04µs 2.8±0.00µs 34.4 Mtx/sec 34.3 Mtx/sec
u32_u64_u64 bsatn 100 1722.1±27.87ns 1671.3±21.52ns 55.4 Mtx/sec 57.1 Mtx/sec
u32_u64_u64 bsatn 100 39.3±0.05ns 39.3±0.08ns 2.4 Gtx/sec 2.4 Gtx/sec
u32_u64_u64 json 100 3.2±0.05µs 3.0±0.01µs 30.2 Mtx/sec 31.5 Mtx/sec
u32_u64_u64 json 100 5.2±0.00µs 5.1±0.09µs 18.4 Mtx/sec 18.8 Mtx/sec
u32_u64_u64 product_value 100 1014.5±1.38ns 1013.4±1.07ns 94.0 Mtx/sec 94.1 Mtx/sec
u64_u64_u32 bflatn_to_bsatn_fast_path 100 892.2±1.94ns 887.8±3.66ns 106.9 Mtx/sec 107.4 Mtx/sec
u64_u64_u32 bflatn_to_bsatn_slow_path 100 2.8±0.01µs 2.8±0.00µs 34.3 Mtx/sec 34.1 Mtx/sec
u64_u64_u32 bsatn 100 1093.3±2.68ns 1092.7±8.37ns 87.2 Mtx/sec 87.3 Mtx/sec
u64_u64_u32 bsatn 100 1701.5±32.51ns 1711.1±23.62ns 56.1 Mtx/sec 55.7 Mtx/sec
u64_u64_u32 json 100 3.2±0.04µs 3.1±0.01µs 30.1 Mtx/sec 31.0 Mtx/sec
u64_u64_u32 json 100 4.9±0.19µs 5.1±0.49µs 19.3 Mtx/sec 18.6 Mtx/sec
u64_u64_u32 product_value 100 1014.9±0.62ns 1015.7±0.55ns 94.0 Mtx/sec 93.9 Mtx/sec

stdb_module_large_arguments

arg size new latency old latency new throughput old throughput
64KiB 109.5±6.71µs 108.9±7.36µs - -

stdb_module_print_bulk

line count new latency old latency new throughput old throughput
1 55.2±5.89µs 52.9±4.34µs - -
100 602.4±8.58µs 568.4±3.98µs - -
1000 3.7±0.65ms 5.1±0.12ms - -

remaining

name new latency old latency new throughput old throughput
special/db_game/circles/load=10 292.7±2.12µs 300.9±1.75µs - -
special/db_game/circles/load=100 291.2±2.80µs 297.6±2.95µs - -
special/db_game/ia_loop/load=10 0.0±0.00ns 0.0±0.00ns - -
special/db_game/ia_loop/load=100 0.0±0.00ns 0.0±0.00ns - -
sqlite/💿/update_bulk/u32_u64_str/unique_0/load=2048/count=256 53.6±0.51µs 55.9±0.46µs 18.2 Ktx/sec 17.5 Ktx/sec
sqlite/💿/update_bulk/u32_u64_u64/unique_0/load=2048/count=256 45.8±0.17µs 46.5±0.24µs 21.3 Ktx/sec 21.0 Ktx/sec
sqlite/🧠/update_bulk/u32_u64_str/unique_0/load=2048/count=256 39.4±0.27µs 40.2±0.35µs 24.8 Ktx/sec 24.3 Ktx/sec
sqlite/🧠/update_bulk/u32_u64_u64/unique_0/load=2048/count=256 35.1±0.23µs 36.0±0.11µs 27.8 Ktx/sec 27.1 Ktx/sec
stdb_module/💿/update_bulk/u32_u64_str/unique_0/load=2048/count=256 1277.2±25.55µs 1260.3±11.34µs 782 tx/sec 793 tx/sec
stdb_module/💿/update_bulk/u32_u64_u64/unique_0/load=2048/count=256 1033.2±17.44µs 972.5±65.67µs 967 tx/sec 1028 tx/sec
stdb_raw/💿/update_bulk/u32_u64_str/unique_0/load=2048/count=256 638.2±20.43µs 642.8±25.10µs 1566 tx/sec 1555 tx/sec
stdb_raw/💿/update_bulk/u32_u64_u64/unique_0/load=2048/count=256 491.4±11.22µs 468.5±25.48µs 2035 tx/sec 2.1 Ktx/sec
stdb_raw/🧠/update_bulk/u32_u64_str/unique_0/load=2048/count=256 379.5±0.34µs 380.8±0.41µs 2.6 Ktx/sec 2.6 Ktx/sec
stdb_raw/🧠/update_bulk/u32_u64_u64/unique_0/load=2048/count=256 340.5±0.27µs 339.0±0.58µs 2.9 Ktx/sec 2.9 Ktx/sec

@github-actions
Copy link

@github-actions github-actions bot commented on df5b78a Oct 11, 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 5386 5385 0.02% 5500 5423 1.42%
sqlite 5509 5519 -0.18% 6009 5995 0.23%

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 75563 75451 0.15% 76205 76099 0.14%
stdb_raw u32_u64_str no_index 64 128 2 string 117974 118951 -0.82% 118846 119811 -0.81%
stdb_raw u32_u64_str btree_each_column 64 128 2 string 24065 24068 -0.01% 24737 24752 -0.06%
stdb_raw u32_u64_str btree_each_column 64 128 1 u64 23033 23036 -0.01% 23595 23500 0.40%
sqlite u32_u64_str no_index 64 128 2 string 144677 144677 0.00% 146139 146253 -0.08%
sqlite u32_u64_str no_index 64 128 1 u64 124027 124027 0.00% 125363 125375 -0.01%
sqlite u32_u64_str btree_each_column 64 128 1 u64 131344 131344 0.00% 132692 132808 -0.09%
sqlite u32_u64_str btree_each_column 64 128 2 string 134476 134476 0.00% 136070 136156 -0.06%

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 902067 902800 -0.08% 949525 950984 -0.15%
stdb_raw u32_u64_str btree_each_column 64 128 1052609 1052756 -0.01% 1118167 1125742 -0.67%
sqlite u32_u64_str unique_0 64 128 398158 398158 0.00% 413020 412960 0.01%
sqlite u32_u64_str btree_each_column 64 128 983475 983475 0.00% 1016491 1018215 -0.17%

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 152816 152705 0.07% 152970 152811 0.10%
stdb_raw u32_u64_str unique_0 64 15841 15730 0.71% 15991 15804 1.18%
sqlite u32_u64_str unique_0 1024 1046659 1046663 -0.00% 1050201 1050119 0.01%
sqlite u32_u64_str unique_0 64 74799 74809 -0.01% 75893 75987 -0.12%

callgrind: serialize_product_value

count format total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
64 json 47374 47374 0.00% 49958 49996 -0.08%
64 bsatn 25716 25716 0.00% 27994 27994 0.00%
16 bsatn 8117 8117 0.00% 9477 9477 0.00%
16 json 12126 12126 0.00% 13962 13996 -0.24%

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 20905561 20712769 0.93% 21409327 21402149 0.03%
stdb_raw u32_u64_str unique_0 64 128 1307940 1307894 0.00% 1374390 1387462 -0.94%
sqlite u32_u64_str unique_0 1024 1024 1802091 1802091 0.00% 1811271 1811095 0.01%
sqlite u32_u64_str unique_0 64 128 128437 128437 0.00% 131297 131237 0.05%
On-disk benchmarks

callgrind: empty transaction

db total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw 5396 5395 0.02% 5510 5437 1.34%
sqlite 5551 5557 -0.11% 6115 6199 -1.36%

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 75573 75461 0.15% 76207 76069 0.18%
stdb_raw u32_u64_str no_index 64 128 2 string 117984 117872 0.10% 118784 118652 0.11%
stdb_raw u32_u64_str btree_each_column 64 128 2 string 24075 24094 -0.08% 24747 24766 -0.08%
stdb_raw u32_u64_str btree_each_column 64 128 1 u64 23043 23046 -0.01% 23601 23506 0.40%
sqlite u32_u64_str no_index 64 128 1 u64 125948 125948 0.00% 127572 127516 0.04%
sqlite u32_u64_str no_index 64 128 2 string 146598 146598 0.00% 148424 148426 -0.00%
sqlite u32_u64_str btree_each_column 64 128 2 string 136598 136598 0.00% 138562 138736 -0.13%
sqlite u32_u64_str btree_each_column 64 128 1 u64 133440 133440 0.00% 135098 135310 -0.16%

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 851285 851115 0.02% 898029 898181 -0.02%
stdb_raw u32_u64_str btree_each_column 64 128 1002178 1001836 0.03% 1066230 1074054 -0.73%
sqlite u32_u64_str unique_0 64 128 415695 415695 0.00% 429823 429859 -0.01%
sqlite u32_u64_str btree_each_column 64 128 1021736 1021736 0.00% 1053364 1056868 -0.33%

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 152826 152715 0.07% 152972 152785 0.12%
stdb_raw u32_u64_str unique_0 64 15851 15740 0.71% 15997 15810 1.18%
sqlite u32_u64_str unique_0 1024 1049721 1049727 -0.00% 1053435 1053525 -0.01%
sqlite u32_u64_str unique_0 64 76571 76571 0.00% 77837 77835 0.00%

callgrind: serialize_product_value

count format total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
64 json 47374 47374 0.00% 49958 49996 -0.08%
64 bsatn 25716 25716 0.00% 27994 27994 0.00%
16 bsatn 8117 8117 0.00% 9477 9477 0.00%
16 json 12126 12126 0.00% 13962 13996 -0.24%

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 19425499 19415679 0.05% 20011577 20230603 -1.08%
stdb_raw u32_u64_str unique_0 64 128 1261172 1260469 0.06% 1327982 1341805 -1.03%
sqlite u32_u64_str unique_0 1024 1024 1809652 1809652 0.00% 1818212 1818268 -0.00%
sqlite u32_u64_str unique_0 64 128 132563 132563 0.00% 135475 135499 -0.02%

Please sign in to comment.