Skip to content

Commit

Permalink
vm: Make UPDATE actually update
Browse files Browse the repository at this point in the history
Previously, an UPDATE statement would be the identity function. Fix this
by threading through the assignments (SET clause) and transforming the
rows matching the query.
  • Loading branch information
kim committed Oct 25, 2023
1 parent bc54b73 commit 3838c89
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 49 deletions.
18 changes: 1 addition & 17 deletions crates/core/src/sql/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,24 +403,8 @@ fn compile_update(
} else {
QueryExpr::new(&table.root)
};
let mut cols = Vec::with_capacity(table.root.columns.len());

for field in table.root.columns.iter() {
let field = FieldName::named(&table.root.table_name, &field.col_name);
if let Some(f) = assignments.get(&field) {
cols.push(f.clone());
} else {
cols.push(FieldExpr::Name(field));
}
}

let insert = QueryExpr::new(&table.root).with_project(&cols, None);
let insert = if let Some(filter) = selection {
compile_where(insert, &table, filter)?
} else {
insert
};
Ok(CrudExpr::Update { insert, delete })
Ok(CrudExpr::Update { delete, assignments })
}

/// Compiles a `CREATE TABLE ...` clause
Expand Down
51 changes: 35 additions & 16 deletions crates/core/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use spacetimedb_lib::relation::{Header, MemTable, RelIter, RelValue, RowCount, T
use spacetimedb_lib::table::ProductTypeMeta;
use spacetimedb_primitives::{ColId, TableId};
use spacetimedb_sats::{AlgebraicValue, ProductValue};
use spacetimedb_vm::dsl::mem_table;
use spacetimedb_vm::env::EnvDb;
use spacetimedb_vm::errors::ErrorVm;
use spacetimedb_vm::eval::IterRows;
Expand Down Expand Up @@ -308,16 +307,6 @@ impl<'db, 'tx> DbProgram<'db, 'tx> {
}
}

fn insert_query(&mut self, table: &Table, query: QueryCode) -> Result<Code, ErrorVm> {
let result = self._eval_query(query)?;
match result {
Code::Table(result) => {
self._execute_insert(table, result.data.into_iter().map(|row| row.data).collect_vec())
}
_ => Ok(result),
}
}

fn create_table(
&mut self,
table_name: &str,
Expand Down Expand Up @@ -402,7 +391,10 @@ impl ProgramVm for DbProgram<'_, '_> {
match query {
CrudCode::Query(query) => self._eval_query(query),
CrudCode::Insert { table, rows } => self._execute_insert(&table, rows),
CrudCode::Update { mut insert, delete } => {
CrudCode::Update {
delete,
mut assignments,
} => {
let table = delete.table.clone();
let result = self._eval_query(delete)?;

Expand All @@ -415,11 +407,38 @@ impl ProgramVm for DbProgram<'_, '_> {
deleted.data.clone().into_iter().map(|row| row.data).collect_vec(),
)?;

let to_insert = mem_table(table.head().clone(), deleted.data.into_iter().map(|row| row.data));
insert.table = Table::MemTable(to_insert);
// Replace the columns in the matched rows with the assigned
// values. No typechecking is performed here, nor that all
// assignments are consumed.
let exprs: Vec<Option<FieldExpr>> = table
.head()
.fields
.iter()
.map(|col| assignments.remove(&col.field))
.collect();
let insert_rows = deleted
.data
.into_iter()
.map(|row| {
let elements = row
.data
.elements
.into_iter()
.zip(&exprs)
.map(|(val, expr)| {
if let Some(FieldExpr::Value(assigned)) = expr {
assigned.clone()
} else {
val
}
})
.collect();

ProductValue { elements }
})
.collect_vec();

let result = self.insert_query(&table, insert)?;
Ok(result)
self._execute_insert(&table, insert_rows)
}
CrudCode::Delete { query } => {
let result = self.delete_query(query)?;
Expand Down
10 changes: 4 additions & 6 deletions crates/vm/src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,10 @@ fn build_typed<P: ProgramVm>(p: &mut P, node: Expr) -> ExprOpt {
}
ExprOpt::Crud(Box::new(CrudExprOpt::Insert { source, rows }))
}
CrudExpr::Update { insert, delete } => {
let insert = build_query_opt(insert);
CrudExpr::Update { delete, assignments } => {
let delete = build_query_opt(delete);

ExprOpt::Crud(Box::new(CrudExprOpt::Update { insert, delete }))
ExprOpt::Crud(Box::new(CrudExprOpt::Update { delete, assignments }))
}
CrudExpr::Delete { query } => {
let query = build_query_opt(query);
Expand Down Expand Up @@ -270,10 +269,9 @@ fn compile<P: ProgramVm>(p: &mut P, node: ExprOpt) -> Result<Code, ErrorVm> {
};
Code::Crud(q)
}
CrudExprOpt::Update { insert, delete } => {
let insert = compile_query(insert);
CrudExprOpt::Update { delete, assignments } => {
let delete = compile_query(delete);
Code::Crud(CrudCode::Update { insert, delete })
Code::Crud(CrudCode::Update { delete, assignments })
}
CrudExprOpt::Delete { query } => {
let query = compile_query(query);
Expand Down
20 changes: 11 additions & 9 deletions crates/vm/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,16 +400,16 @@ pub enum Crud {
Drop(DbType),
}

#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord)]
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum CrudExpr {
Query(QueryExpr),
Insert {
source: SourceExpr,
rows: Vec<Vec<FieldExpr>>,
},
Update {
insert: QueryExpr,
delete: QueryExpr,
assignments: HashMap<FieldName, FieldExpr>,
},
Delete {
query: QueryExpr,
Expand Down Expand Up @@ -1081,8 +1081,8 @@ pub enum CrudExprOpt {
rows: Vec<ProductValue>,
},
Update {
insert: QueryExprOpt,
delete: QueryExprOpt,
assignments: HashMap<FieldName, FieldExpr>,
},
Delete {
query: QueryExprOpt,
Expand Down Expand Up @@ -1343,8 +1343,8 @@ pub enum CrudCode {
rows: Vec<ProductValue>,
},
Update {
insert: QueryCode,
delete: QueryCode,
assignments: HashMap<FieldName, FieldExpr>,
},
Delete {
query: QueryCode,
Expand Down Expand Up @@ -1576,11 +1576,13 @@ mod tests {

#[test]
fn test_auth_crud_code_update() {
let mut qc = query_codes().into_iter();
let insert = qc.next().unwrap();
let delete = qc.next().unwrap();
let crud = CrudCode::Update { insert, delete };
assert_owner_required(crud);
for qc in query_codes() {
let crud = CrudCode::Update {
delete: qc,
assignments: Default::default(),
};
assert_owner_required(crud);
}
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion crates/vm/src/typecheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ pub(crate) fn check_types(env: &mut EnvTy, ast: &ExprOpt) -> Result<Ty, ErrorTyp
let q = &**q;
match q {
CrudExprOpt::Insert { source, .. } => Ok(ty_source(source)),
CrudExprOpt::Update { insert, .. } => Ok(ty_source(&insert.source)),
CrudExprOpt::Update { delete, .. } => Ok(ty_source(&delete.source)),
CrudExprOpt::Delete { query } => Ok(ty_source(&query.source)),
CrudExprOpt::CreateTable { columns, .. } => Ok(AlgebraicType::Product(columns.columns.clone()).into()),
CrudExprOpt::Drop { .. } => {
Expand Down

1 comment on commit 3838c89

@github-actions
Copy link

Choose a reason for hiding this comment

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

Benchmark results

Benchmark Report

Legend:

  • load: number of rows pre-loaded into the database
  • count: number of rows touched by the transaction
  • index types:
    • unique: a single index on the id column
    • non_unique: no indexes
    • multi_index: non-unique index on every column
  • schemas:
    • person(id: u32, name: String, age: u64)
    • location(id: u32, x: u64, y: u64)

All throughputs are single-threaded.

Empty transaction

db on disk new latency old latency new throughput old throughput
sqlite 💿 441.3±2.95ns 467.0±4.38ns - -
sqlite 🧠 435.2±2.32ns 448.5±2.32ns - -
stdb_module 💿 16.2±0.45µs 16.1±0.50µs - -
stdb_module 🧠 16.3±0.39µs 16.4±0.66µs - -
stdb_raw 💿 189.9±0.31ns 189.8±2.81ns - -
stdb_raw 🧠 190.3±0.20ns 190.1±2.84ns - -

Single-row insertions

db on disk schema index type load new latency old latency new throughput old throughput
sqlite 💿 location multi_index 0 14.6±0.13µs 14.7±0.61µs 66.7 Ktx/sec 66.4 Ktx/sec
sqlite 💿 location multi_index 1000 16.1±0.15µs 18.0±21.10µs 60.8 Ktx/sec 54.4 Ktx/sec
sqlite 💿 location non_unique 0 7.5±1.03µs 7.3±1.05µs 130.3 Ktx/sec 133.1 Ktx/sec
sqlite 💿 location non_unique 1000 7.1±0.03µs 7.0±0.03µs 136.7 Ktx/sec 138.6 Ktx/sec
sqlite 💿 location unique 0 7.4±0.20µs 7.2±0.04µs 132.8 Ktx/sec 136.1 Ktx/sec
sqlite 💿 location unique 1000 7.2±0.05µs 7.1±0.03µs 135.4 Ktx/sec 137.6 Ktx/sec
sqlite 💿 person multi_index 0 14.8±0.24µs 14.3±0.05µs 65.9 Ktx/sec 68.4 Ktx/sec
sqlite 💿 person multi_index 1000 16.3±0.10µs 16.2±0.11µs 59.8 Ktx/sec 60.1 Ktx/sec
sqlite 💿 person non_unique 0 7.5±0.46µs 7.3±0.04µs 130.6 Ktx/sec 134.5 Ktx/sec
sqlite 💿 person non_unique 1000 7.3±0.03µs 7.3±0.03µs 132.9 Ktx/sec 133.9 Ktx/sec
sqlite 💿 person unique 0 7.5±0.50µs 7.4±0.80µs 130.7 Ktx/sec 132.9 Ktx/sec
sqlite 💿 person unique 1000 7.4±0.04µs 7.3±0.07µs 132.7 Ktx/sec 133.4 Ktx/sec
sqlite 🧠 location multi_index 0 4.1±0.03µs 4.0±0.01µs 237.8 Ktx/sec 243.0 Ktx/sec
sqlite 🧠 location multi_index 1000 5.3±0.04µs 5.3±0.05µs 183.4 Ktx/sec 184.2 Ktx/sec
sqlite 🧠 location non_unique 0 1883.6±5.20ns 1862.0±5.56ns 518.5 Ktx/sec 524.5 Ktx/sec
sqlite 🧠 location non_unique 1000 1944.6±25.09ns 1923.1±10.83ns 502.2 Ktx/sec 507.8 Ktx/sec
sqlite 🧠 location unique 0 1873.3±5.56ns 1857.2±10.34ns 521.3 Ktx/sec 525.8 Ktx/sec
sqlite 🧠 location unique 1000 1976.0±15.45ns 1975.6±17.45ns 494.2 Ktx/sec 494.3 Ktx/sec
sqlite 🧠 person multi_index 0 3.7±0.01µs 3.7±0.01µs 264.0 Ktx/sec 265.2 Ktx/sec
sqlite 🧠 person multi_index 1000 5.5±0.03µs 5.5±0.03µs 178.0 Ktx/sec 177.8 Ktx/sec
sqlite 🧠 person non_unique 0 1941.8±9.62ns 1920.5±4.10ns 502.9 Ktx/sec 508.5 Ktx/sec
sqlite 🧠 person non_unique 1000 2.0±0.01µs 2.0±0.02µs 482.8 Ktx/sec 480.0 Ktx/sec
sqlite 🧠 person unique 0 1926.7±16.75ns 1904.6±8.19ns 506.8 Ktx/sec 512.7 Ktx/sec
sqlite 🧠 person unique 1000 2.1±0.01µs 2.0±0.01µs 471.1 Ktx/sec 477.4 Ktx/sec
stdb_module 💿 location multi_index 0 43.2±5.22µs 41.3±5.21µs 22.6 Ktx/sec 23.6 Ktx/sec
stdb_module 💿 location multi_index 1000 112.8±22.23µs 126.1±23.85µs 8.7 Ktx/sec 7.7 Ktx/sec
stdb_module 💿 location non_unique 0 34.6±2.57µs 35.5±3.89µs 28.2 Ktx/sec 27.5 Ktx/sec
stdb_module 💿 location non_unique 1000 114.6±23.50µs 293.5±3.53µs 8.5 Ktx/sec 3.3 Ktx/sec
stdb_module 💿 location unique 0 37.9±4.94µs 40.8±3.95µs 25.8 Ktx/sec 24.0 Ktx/sec
stdb_module 💿 location unique 1000 251.3±19.87µs 108.5±6.68µs 3.9 Ktx/sec 9.0 Ktx/sec
stdb_module 💿 person multi_index 0 53.0±8.11µs 50.9±5.40µs 18.4 Ktx/sec 19.2 Ktx/sec
stdb_module 💿 person multi_index 1000 296.0±11.73µs 211.7±104.85µs 3.3 Ktx/sec 4.6 Ktx/sec
stdb_module 💿 person non_unique 0 36.2±3.44µs 35.6±3.57µs 27.0 Ktx/sec 27.4 Ktx/sec
stdb_module 💿 person non_unique 1000 269.2±36.72µs 186.8±10.51µs 3.6 Ktx/sec 5.2 Ktx/sec
stdb_module 💿 person unique 0 46.8±5.79µs 50.6±5.07µs 20.9 Ktx/sec 19.3 Ktx/sec
stdb_module 💿 person unique 1000 228.9±41.18µs 147.6±10.38µs 4.3 Ktx/sec 6.6 Ktx/sec
stdb_module 🧠 location multi_index 0 34.2±3.45µs 32.9±1.87µs 28.6 Ktx/sec 29.7 Ktx/sec
stdb_module 🧠 location multi_index 1000 96.8±3.17µs 250.3±11.24µs 10.1 Ktx/sec 3.9 Ktx/sec
stdb_module 🧠 location non_unique 0 28.9±2.41µs 28.6±2.00µs 33.8 Ktx/sec 34.2 Ktx/sec
stdb_module 🧠 location non_unique 1000 250.9±26.77µs 274.5±4.62µs 3.9 Ktx/sec 3.6 Ktx/sec
stdb_module 🧠 location unique 0 30.2±1.86µs 31.8±2.90µs 32.3 Ktx/sec 30.7 Ktx/sec
stdb_module 🧠 location unique 1000 229.3±37.90µs 230.2±4.07µs 4.3 Ktx/sec 4.2 Ktx/sec
stdb_module 🧠 person multi_index 0 40.5±3.65µs 41.6±4.87µs 24.1 Ktx/sec 23.5 Ktx/sec
stdb_module 🧠 person multi_index 1000 154.1±17.30µs 316.1±3.85µs 6.3 Ktx/sec 3.1 Ktx/sec
stdb_module 🧠 person non_unique 0 30.7±2.22µs 31.0±3.08µs 31.9 Ktx/sec 31.5 Ktx/sec
stdb_module 🧠 person non_unique 1000 231.6±20.12µs 143.7±6.37µs 4.2 Ktx/sec 6.8 Ktx/sec
stdb_module 🧠 person unique 0 33.8±1.83µs 34.2±3.42µs 28.9 Ktx/sec 28.5 Ktx/sec
stdb_module 🧠 person unique 1000 192.2±3.00µs 192.6±5.89µs 5.1 Ktx/sec 5.1 Ktx/sec
stdb_raw 💿 location multi_index 0 6.3±0.52µs 6.3±0.02µs 153.8 Ktx/sec 155.4 Ktx/sec
stdb_raw 💿 location multi_index 1000 8.8±0.16µs 8.7±0.17µs 110.7 Ktx/sec 112.0 Ktx/sec
stdb_raw 💿 location non_unique 0 3.9±0.01µs 4.0±0.06µs 247.4 Ktx/sec 247.2 Ktx/sec
stdb_raw 💿 location non_unique 1000 12.0±67.13µs 5.2±0.14µs 81.6 Ktx/sec 188.8 Ktx/sec
stdb_raw 💿 location unique 0 5.3±0.01µs 5.3±0.19µs 184.7 Ktx/sec 185.5 Ktx/sec
stdb_raw 💿 location unique 1000 20.3±128.30µs 23.3±159.73µs 48.0 Ktx/sec 41.9 Ktx/sec
stdb_raw 💿 person multi_index 0 10.0±0.02µs 9.9±0.01µs 97.9 Ktx/sec 98.7 Ktx/sec
stdb_raw 💿 person multi_index 1000 48.4±353.95µs 12.9±0.32µs 20.2 Ktx/sec 75.5 Ktx/sec
stdb_raw 💿 person non_unique 0 4.5±0.20µs 4.9±0.31µs 215.6 Ktx/sec 198.0 Ktx/sec
stdb_raw 💿 person non_unique 1000 17.3±112.36µs 28.4±157.31µs 56.5 Ktx/sec 34.4 Ktx/sec
stdb_raw 💿 person unique 0 6.8±0.04µs 6.9±0.03µs 142.7 Ktx/sec 142.4 Ktx/sec
stdb_raw 💿 person unique 1000 9.3±0.50µs 30.5±213.00µs 105.5 Ktx/sec 32.0 Ktx/sec
stdb_raw 🧠 location multi_index 0 4.8±0.01µs 4.8±0.01µs 203.1 Ktx/sec 203.5 Ktx/sec
stdb_raw 🧠 location multi_index 1000 6.4±0.06µs 6.4±0.07µs 152.6 Ktx/sec 153.4 Ktx/sec
stdb_raw 🧠 location non_unique 0 2.5±0.01µs 2.5±0.02µs 385.2 Ktx/sec 387.6 Ktx/sec
stdb_raw 🧠 location non_unique 1000 3.2±0.03µs 3.2±0.03µs 307.4 Ktx/sec 305.4 Ktx/sec
stdb_raw 🧠 location unique 0 3.8±0.01µs 3.8±0.01µs 255.6 Ktx/sec 258.7 Ktx/sec
stdb_raw 🧠 location unique 1000 5.1±0.04µs 5.1±0.07µs 191.1 Ktx/sec 190.2 Ktx/sec
stdb_raw 🧠 person multi_index 0 8.4±0.02µs 8.4±0.03µs 115.8 Ktx/sec 116.0 Ktx/sec
stdb_raw 🧠 person multi_index 1000 10.4±0.09µs 10.4±0.10µs 94.0 Ktx/sec 93.9 Ktx/sec
stdb_raw 🧠 person non_unique 0 3.1±0.01µs 3.1±0.01µs 315.8 Ktx/sec 317.5 Ktx/sec
stdb_raw 🧠 person non_unique 1000 3.7±0.04µs 3.8±0.02µs 262.0 Ktx/sec 259.5 Ktx/sec
stdb_raw 🧠 person unique 0 5.4±0.01µs 5.4±0.01µs 182.2 Ktx/sec 182.4 Ktx/sec
stdb_raw 🧠 person unique 1000 6.8±0.06µs 6.8±0.07µs 144.1 Ktx/sec 143.5 Ktx/sec

Multi-row insertions

db on disk schema index type load count new latency old latency new throughput old throughput
sqlite 💿 location multi_index 0 100 132.3±2.37µs 132.5±2.23µs 7.4 Ktx/sec 7.4 Ktx/sec
sqlite 💿 location multi_index 1000 100 203.5±1.76µs 204.2±1.25µs 4.8 Ktx/sec 4.8 Ktx/sec
sqlite 💿 location non_unique 0 100 50.7±0.90µs 51.3±1.06µs 19.3 Ktx/sec 19.0 Ktx/sec
sqlite 💿 location non_unique 1000 100 53.2±0.50µs 53.6±0.29µs 18.4 Ktx/sec 18.2 Ktx/sec
sqlite 💿 location unique 0 100 52.3±0.90µs 53.6±2.61µs 18.7 Ktx/sec 18.2 Ktx/sec
sqlite 💿 location unique 1000 100 57.6±7.58µs 58.1±0.64µs 17.0 Ktx/sec 16.8 Ktx/sec
sqlite 💿 person multi_index 0 100 118.7±2.98µs 119.5±2.66µs 8.2 Ktx/sec 8.2 Ktx/sec
sqlite 💿 person multi_index 1000 100 234.1±30.23µs 233.1±0.71µs 4.2 Ktx/sec 4.2 Ktx/sec
sqlite 💿 person non_unique 0 100 48.4±0.28µs 49.7±1.60µs 20.2 Ktx/sec 19.6 Ktx/sec
sqlite 💿 person non_unique 1000 100 59.7±0.35µs 61.5±0.21µs 16.4 Ktx/sec 15.9 Ktx/sec
sqlite 💿 person unique 0 100 49.4±1.15µs 50.8±1.25µs 19.8 Ktx/sec 19.2 Ktx/sec
sqlite 💿 person unique 1000 100 56.1±0.28µs 57.4±10.98µs 17.4 Ktx/sec 17.0 Ktx/sec
sqlite 🧠 location multi_index 0 100 120.8±0.45µs 120.9±0.46µs 8.1 Ktx/sec 8.1 Ktx/sec
sqlite 🧠 location multi_index 1000 100 170.7±0.52µs 172.3±0.46µs 5.7 Ktx/sec 5.7 Ktx/sec
sqlite 🧠 location non_unique 0 100 43.4±0.40µs 45.6±0.47µs 22.5 Ktx/sec 21.4 Ktx/sec
sqlite 🧠 location non_unique 1000 100 45.1±0.40µs 46.4±0.29µs 21.7 Ktx/sec 21.0 Ktx/sec
sqlite 🧠 location unique 0 100 45.3±0.44µs 46.8±0.37µs 21.6 Ktx/sec 20.9 Ktx/sec
sqlite 🧠 location unique 1000 100 48.8±0.24µs 50.6±0.50µs 20.0 Ktx/sec 19.3 Ktx/sec
sqlite 🧠 person multi_index 0 100 107.6±0.36µs 109.2±0.42µs 9.1 Ktx/sec 8.9 Ktx/sec
sqlite 🧠 person multi_index 1000 100 188.7±0.29µs 190.7±0.53µs 5.2 Ktx/sec 5.1 Ktx/sec
sqlite 🧠 person non_unique 0 100 41.4±0.29µs 43.9±0.44µs 23.6 Ktx/sec 22.2 Ktx/sec
sqlite 🧠 person non_unique 1000 100 44.9±0.35µs 47.0±0.35µs 21.7 Ktx/sec 20.8 Ktx/sec
sqlite 🧠 person unique 0 100 43.5±0.42µs 45.2±0.54µs 22.5 Ktx/sec 21.6 Ktx/sec
sqlite 🧠 person unique 1000 100 47.2±0.25µs 49.5±0.44µs 20.7 Ktx/sec 19.7 Ktx/sec
stdb_module 💿 location multi_index 0 100 799.8±160.07µs 897.2±43.71µs 1250 tx/sec 1114 tx/sec
stdb_module 💿 location multi_index 1000 100 1114.6±129.25µs 1154.8±106.65µs 897 tx/sec 865 tx/sec
stdb_module 💿 location non_unique 0 100 516.3±2.03µs 532.5±8.33µs 1937 tx/sec 1878 tx/sec
stdb_module 💿 location non_unique 1000 100 354.5±7.57µs 550.2±4.22µs 2.8 Ktx/sec 1817 tx/sec
stdb_module 💿 location unique 0 100 504.5±4.42µs 509.4±38.37µs 1982 tx/sec 1963 tx/sec
stdb_module 💿 location unique 1000 100 605.7±81.72µs 634.8±106.24µs 1650 tx/sec 1575 tx/sec
stdb_module 💿 person multi_index 0 100 894.1±52.27µs 927.1±8.33µs 1118 tx/sec 1078 tx/sec
stdb_module 💿 person multi_index 1000 100 995.7±7.94µs 1096.7±34.06µs 1004 tx/sec 911 tx/sec
stdb_module 💿 person non_unique 0 100 541.4±91.07µs 478.8±15.65µs 1846 tx/sec 2.0 Ktx/sec
stdb_module 💿 person non_unique 1000 100 476.6±30.32µs 648.2±29.07µs 2.0 Ktx/sec 1542 tx/sec
stdb_module 💿 person unique 0 100 595.2±1.60µs 655.9±56.64µs 1679 tx/sec 1524 tx/sec
stdb_module 💿 person unique 1000 100 677.2±3.16µs 930.9±36.81µs 1476 tx/sec 1074 tx/sec
stdb_module 🧠 location multi_index 0 100 578.7±39.25µs 648.9±137.82µs 1728 tx/sec 1541 tx/sec
stdb_module 🧠 location multi_index 1000 100 1033.8±37.71µs 686.4±14.14µs 967 tx/sec 1456 tx/sec
stdb_module 🧠 location non_unique 0 100 305.3±5.68µs 402.8±26.28µs 3.2 Ktx/sec 2.4 Ktx/sec
stdb_module 🧠 location non_unique 1000 100 398.5±3.07µs 610.7±3.52µs 2.5 Ktx/sec 1637 tx/sec
stdb_module 🧠 location unique 0 100 446.3±1.64µs 476.8±2.43µs 2.2 Ktx/sec 2.0 Ktx/sec
stdb_module 🧠 location unique 1000 100 480.5±2.55µs 759.6±54.70µs 2.0 Ktx/sec 1316 tx/sec
stdb_module 🧠 person multi_index 0 100 837.6±3.27µs 956.7±20.22µs 1193 tx/sec 1045 tx/sec
stdb_module 🧠 person multi_index 1000 100 982.0±90.70µs 1043.7±4.47µs 1018 tx/sec 958 tx/sec
stdb_module 🧠 person non_unique 0 100 336.8±24.50µs 386.9±48.66µs 2.9 Ktx/sec 2.5 Ktx/sec
stdb_module 🧠 person non_unique 1000 100 658.2±47.15µs 477.4±4.38µs 1519 tx/sec 2.0 Ktx/sec
stdb_module 🧠 person unique 0 100 636.9±8.92µs 631.8±39.54µs 1570 tx/sec 1582 tx/sec
stdb_module 🧠 person unique 1000 100 638.7±36.22µs 810.1±57.15µs 1565 tx/sec 1234 tx/sec
stdb_raw 💿 location multi_index 0 100 368.2±0.53µs 367.1±0.74µs 2.7 Ktx/sec 2.7 Ktx/sec
stdb_raw 💿 location multi_index 1000 100 412.7±182.91µs 415.7±229.40µs 2.4 Ktx/sec 2.3 Ktx/sec
stdb_raw 💿 location non_unique 0 100 141.7±4.61µs 140.9±0.36µs 6.9 Ktx/sec 6.9 Ktx/sec
stdb_raw 💿 location non_unique 1000 100 143.9±1.02µs 142.9±1.04µs 6.8 Ktx/sec 6.8 Ktx/sec
stdb_raw 💿 location unique 0 100 269.0±0.35µs 268.5±9.46µs 3.6 Ktx/sec 3.6 Ktx/sec
stdb_raw 💿 location unique 1000 100 306.1±161.81µs 303.7±160.11µs 3.2 Ktx/sec 3.2 Ktx/sec
stdb_raw 💿 person multi_index 0 100 690.2±0.59µs 685.1±1.94µs 1448 tx/sec 1459 tx/sec
stdb_raw 💿 person multi_index 1000 100 721.1±1.50µs 717.8±6.07µs 1386 tx/sec 1393 tx/sec
stdb_raw 💿 person non_unique 0 100 198.2±0.49µs 198.8±0.51µs 4.9 Ktx/sec 4.9 Ktx/sec
stdb_raw 💿 person non_unique 1000 100 210.7±93.86µs 211.9±98.76µs 4.6 Ktx/sec 4.6 Ktx/sec
stdb_raw 💿 person unique 0 100 410.8±0.45µs 408.6±0.56µs 2.4 Ktx/sec 2.4 Ktx/sec
stdb_raw 💿 person unique 1000 100 454.6±232.64µs 447.9±181.70µs 2.1 Ktx/sec 2.2 Ktx/sec
stdb_raw 🧠 location multi_index 0 100 360.2±0.47µs 362.7±0.67µs 2.7 Ktx/sec 2.7 Ktx/sec
stdb_raw 🧠 location multi_index 1000 100 387.0±0.74µs 389.6±0.77µs 2.5 Ktx/sec 2.5 Ktx/sec
stdb_raw 🧠 location non_unique 0 100 137.5±0.11µs 136.9±0.14µs 7.1 Ktx/sec 7.1 Ktx/sec
stdb_raw 🧠 location non_unique 1000 100 139.7±0.18µs 139.0±0.73µs 7.0 Ktx/sec 7.0 Ktx/sec
stdb_raw 🧠 location unique 0 100 264.5±0.35µs 266.1±2.08µs 3.7 Ktx/sec 3.7 Ktx/sec
stdb_raw 🧠 location unique 1000 100 284.6±0.62µs 287.2±3.33µs 3.4 Ktx/sec 3.4 Ktx/sec
stdb_raw 🧠 person multi_index 0 100 683.3±1.66µs 679.2±0.58µs 1463 tx/sec 1472 tx/sec
stdb_raw 🧠 person multi_index 1000 100 715.0±0.88µs 712.1±1.25µs 1398 tx/sec 1404 tx/sec
stdb_raw 🧠 person non_unique 0 100 193.4±0.23µs 193.3±0.76µs 5.1 Ktx/sec 5.1 Ktx/sec
stdb_raw 🧠 person non_unique 1000 100 196.0±0.51µs 196.0±0.24µs 5.0 Ktx/sec 5.0 Ktx/sec
stdb_raw 🧠 person unique 0 100 404.3±1.15µs 404.9±1.67µs 2.4 Ktx/sec 2.4 Ktx/sec
stdb_raw 🧠 person unique 1000 100 424.4±0.71µs 425.7±3.57µs 2.3 Ktx/sec 2.3 Ktx/sec

Full table iterate

db on disk schema index type new latency old latency new throughput old throughput
sqlite 💿 location unique 8.8±0.10µs 9.1±0.08µs 110.5 Ktx/sec 107.2 Ktx/sec
sqlite 💿 person unique 9.3±0.06µs 9.7±0.09µs 104.7 Ktx/sec 101.2 Ktx/sec
sqlite 🧠 location unique 7.7±0.09µs 7.9±0.06µs 126.1 Ktx/sec 123.6 Ktx/sec
sqlite 🧠 person unique 8.0±0.04µs 8.5±0.08µs 122.2 Ktx/sec 115.3 Ktx/sec
stdb_module 💿 location unique 46.0±6.58µs 46.7±5.17µs 21.2 Ktx/sec 20.9 Ktx/sec
stdb_module 💿 person unique 57.0±9.65µs 56.0±9.46µs 17.1 Ktx/sec 17.4 Ktx/sec
stdb_module 🧠 location unique 44.5±3.44µs 46.7±5.20µs 22.0 Ktx/sec 20.9 Ktx/sec
stdb_module 🧠 person unique 61.5±6.28µs 60.9±6.07µs 15.9 Ktx/sec 16.0 Ktx/sec
stdb_raw 💿 location unique 8.1±0.02µs 8.2±0.01µs 120.1 Ktx/sec 119.0 Ktx/sec
stdb_raw 💿 person unique 8.2±0.03µs 8.2±0.01µs 119.7 Ktx/sec 119.0 Ktx/sec
stdb_raw 🧠 location unique 8.1±0.02µs 8.2±0.03µs 120.0 Ktx/sec 118.9 Ktx/sec
stdb_raw 🧠 person unique 8.1±0.02µs 8.2±0.01µs 119.9 Ktx/sec 118.9 Ktx/sec

Find unique key

db on disk key type load new latency old latency new throughput old throughput
sqlite 💿 u32 1000 2.4±0.01µs 2.4±0.01µs 405.8 Ktx/sec 406.8 Ktx/sec
sqlite 🧠 u32 1000 1124.0±3.57ns 1143.0±4.64ns 868.8 Ktx/sec 854.4 Ktx/sec
stdb_module 💿 u32 1000 19.6±0.89µs 19.7±0.94µs 49.8 Ktx/sec 49.7 Ktx/sec
stdb_module 🧠 u32 1000 19.4±0.72µs 19.5±0.76µs 50.5 Ktx/sec 50.1 Ktx/sec
stdb_raw 💿 u32 1000 881.3±4.04ns 872.3±2.30ns 1108.1 Ktx/sec 1119.6 Ktx/sec
stdb_raw 🧠 u32 1000 880.2±2.64ns 871.9±11.38ns 1109.5 Ktx/sec 1120.0 Ktx/sec

Filter

db on disk key type index strategy load count new latency old latency new throughput old throughput
sqlite 💿 string indexed 1000 10 5.6±0.01µs 5.8±0.02µs 173.1 Ktx/sec 169.2 Ktx/sec
sqlite 💿 string non_indexed 1000 10 50.6±0.23µs 53.4±1.01µs 19.3 Ktx/sec 18.3 Ktx/sec
sqlite 💿 u64 indexed 1000 10 5.5±0.01µs 5.5±0.02µs 178.4 Ktx/sec 178.8 Ktx/sec
sqlite 💿 u64 non_indexed 1000 10 33.2±0.21µs 34.5±0.19µs 29.4 Ktx/sec 28.3 Ktx/sec
sqlite 🧠 string indexed 1000 10 4.2±0.01µs 4.2±0.02µs 232.9 Ktx/sec 232.1 Ktx/sec
sqlite 🧠 string non_indexed 1000 10 49.7±0.30µs 52.0±0.95µs 19.7 Ktx/sec 18.8 Ktx/sec
sqlite 🧠 u64 indexed 1000 10 4.0±0.01µs 4.0±0.02µs 241.6 Ktx/sec 244.5 Ktx/sec
sqlite 🧠 u64 non_indexed 1000 10 31.7±0.06µs 33.2±0.23µs 30.8 Ktx/sec 29.4 Ktx/sec
stdb_module 💿 string indexed 1000 10 29.7±2.87µs 30.1±2.52µs 32.8 Ktx/sec 32.4 Ktx/sec
stdb_module 💿 string non_indexed 1000 10 178.8±1.22µs 182.7±7.39µs 5.5 Ktx/sec 5.3 Ktx/sec
stdb_module 💿 u64 indexed 1000 10 24.5±1.46µs 24.9±2.12µs 39.9 Ktx/sec 39.2 Ktx/sec
stdb_module 💿 u64 non_indexed 1000 10 149.8±2.07µs 162.9±6.77µs 6.5 Ktx/sec 6.0 Ktx/sec
stdb_module 🧠 string indexed 1000 10 31.1±2.43µs 28.3±2.19µs 31.4 Ktx/sec 34.5 Ktx/sec
stdb_module 🧠 string non_indexed 1000 10 176.6±1.33µs 182.8±2.98µs 5.5 Ktx/sec 5.3 Ktx/sec
stdb_module 🧠 u64 indexed 1000 10 24.1±1.58µs 24.2±1.68µs 40.5 Ktx/sec 40.3 Ktx/sec
stdb_module 🧠 u64 non_indexed 1000 10 152.9±6.58µs 158.2±3.66µs 6.4 Ktx/sec 6.2 Ktx/sec
stdb_raw 💿 string indexed 1000 10 3.4±0.01µs 3.2±0.01µs 288.6 Ktx/sec 301.0 Ktx/sec
stdb_raw 💿 string non_indexed 1000 10 145.0±0.61µs 142.8±0.47µs 6.7 Ktx/sec 6.8 Ktx/sec
stdb_raw 💿 u64 indexed 1000 10 3.3±0.03µs 3.1±0.01µs 300.1 Ktx/sec 310.1 Ktx/sec
stdb_raw 💿 u64 non_indexed 1000 10 117.0±0.15µs 122.3±0.25µs 8.3 Ktx/sec 8.0 Ktx/sec
stdb_raw 🧠 string indexed 1000 10 3.3±0.01µs 3.3±0.04µs 292.3 Ktx/sec 299.8 Ktx/sec
stdb_raw 🧠 string non_indexed 1000 10 144.3±1.66µs 142.6±0.38µs 6.8 Ktx/sec 6.9 Ktx/sec
stdb_raw 🧠 u64 indexed 1000 10 3.2±0.01µs 3.1±0.01µs 301.2 Ktx/sec 311.0 Ktx/sec
stdb_raw 🧠 u64 non_indexed 1000 10 116.7±0.27µs 121.9±0.14µs 8.4 Ktx/sec 8.0 Ktx/sec

Serialize

schema format count new latency old latency new throughput old throughput
location bsatn 100 1887.3±31.05ns 1711.5±50.39ns 50.5 Mtx/sec 55.7 Mtx/sec
location json 100 3.2±0.01µs 3.4±0.05µs 30.3 Mtx/sec 28.1 Mtx/sec
location product_value 100 1120.5±0.65ns 1119.9±0.69ns 85.1 Mtx/sec 85.2 Mtx/sec
person bsatn 100 2.7±0.04µs 2.9±0.01µs 35.4 Mtx/sec 33.1 Mtx/sec
person json 100 5.2±0.02µs 5.0±0.08µs 18.3 Mtx/sec 18.9 Mtx/sec
person product_value 100 1113.4±1.34ns 1114.3±0.93ns 85.7 Mtx/sec 85.6 Mtx/sec

Module: invoke with large arguments

arg size new latency old latency new throughput old throughput
64KiB 82.7±5.33µs 76.0±6.93µs - -

Module: print bulk

line count new latency old latency new throughput old throughput
1 20.0±0.69µs 20.4±0.79µs - -
100 201.8±0.65µs 202.9±8.76µs - -
1000 1836.4±38.99µs 1825.2±18.29µs - -

Remaining benchmarks

name new latency old latency new throughput old throughput

Please sign in to comment.