Skip to content

Commit

Permalink
[ABI] Remove the special first element of iterator (#420)
Browse files Browse the repository at this point in the history
  • Loading branch information
RReverser authored Oct 16, 2023
1 parent a952b19 commit 469dff6
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 69 deletions.
12 changes: 5 additions & 7 deletions crates/bindings-csharp/Runtime/Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,20 +140,18 @@ public void Reset()

public class RawTableIter : IEnumerable<byte[]>
{
public readonly byte[] Schema;

private readonly IEnumerator<byte[]> iter;
private readonly uint tableId;
private readonly byte[]? filterBytes;

public RawTableIter(uint tableId, byte[]? filterBytes = null)
{
iter = new BufferIter(tableId, filterBytes);
iter.MoveNext();
Schema = iter.Current;
this.tableId = tableId;
this.filterBytes = filterBytes;
}

public IEnumerator<byte[]> GetEnumerator()
{
return iter;
return new BufferIter(tableId, filterBytes);
}

IEnumerator IEnumerable.GetEnumerator()
Expand Down
2 changes: 1 addition & 1 deletion crates/bindings-csharp/Runtime/bindings.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ static MonoArray* stdb_buffer_consume(Buffer buf);
// return out;
// }

#define STDB_IMPORT_MODULE_MINOR(minor) "spacetime_6." #minor
#define STDB_IMPORT_MODULE_MINOR(minor) "spacetime_7." #minor
#define STDB_IMPORT_MODULE STDB_IMPORT_MODULE_MINOR(0)

__attribute__((import_module(STDB_IMPORT_MODULE),
Expand Down
2 changes: 1 addition & 1 deletion crates/bindings-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub mod raw {
// on. Any non-breaking additions to the abi surface should be put in a new `extern {}` block
// with a module identifier with a minor version 1 above the previous highest minor version.
// For breaking changes, all functions should be moved into one new `spacetime_X.0` block.
#[link(wasm_import_module = "spacetime_6.0")]
#[link(wasm_import_module = "spacetime_7.0")]
extern "C" {
/*
/// Create a table with `name`, a UTF-8 slice in WASM memory lasting `name_len` bytes,
Expand Down
42 changes: 11 additions & 31 deletions crates/bindings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,34 +245,6 @@ pub fn delete_range(table_id: u32, col_id: u8, range: Range<AlgebraicValue>) ->
//
// }

// Get the buffer iterator for this table,
// with an optional filter,
// and return it and its decoded `ProductType` schema.
fn buffer_table_iter(
table_id: u32,
filter: Option<spacetimedb_lib::filter::Expr>,
) -> Result<(BufferIter, ProductType)> {
// Decode the filter, if any.
let filter = filter
.as_ref()
.map(bsatn::to_vec)
.transpose()
.expect("Couldn't decode the filter query");

// Create the iterator.
let mut iter = sys::iter(table_id, filter.as_deref())?;

// First item is an encoded schema.
let schema_raw = iter
.next()
.expect("Missing schema")
.expect("Failed to get schema")
.read();
let schema = decode_schema(&mut &schema_raw[..]).expect("Could not decode schema");

Ok((iter, schema))
}

/// A table iterator which yields `ProductValue`s.
// type ProductValueTableIter = RawTableIter<ProductValue, ProductValueBufferDeserialize>;

Expand All @@ -285,10 +257,18 @@ fn buffer_table_iter(
/// A table iterator which yields values of the `TableType` corresponding to the table.
type TableTypeTableIter<T> = RawTableIter<TableTypeBufferDeserialize<T>>;

// Get the iterator for this table with an optional filter,
fn table_iter<T: TableType>(table_id: u32, filter: Option<spacetimedb_lib::filter::Expr>) -> Result<TableIter<T>> {
// The TableType deserializer doesn't need the schema, as we have type-directed
// dispatch to deserialize any given `TableType`.
let (iter, _schema) = buffer_table_iter(table_id, filter)?;
// Decode the filter, if any.
let filter = filter
.as_ref()
.map(bsatn::to_vec)
.transpose()
.expect("Couldn't decode the filter query");

// Create the iterator.
let iter = sys::iter(table_id, filter.as_deref())?;

let deserializer = TableTypeBufferDeserialize::new();
Ok(RawTableIter::new(iter, deserializer).into())
}
Expand Down
37 changes: 11 additions & 26 deletions crates/core/src/host/instance_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@ impl BufWriter for ChunkedWriter {
}

impl ChunkedWriter {
/// Flushes the currently populated part of the scratch space as a new chunk.
pub fn force_flush(&mut self) {
if !self.scratch_space.is_empty() {
/// Flushes the data collected in the scratch space if it's larger than our
/// chunking threshold.
pub fn flush(&mut self) {
// For now, just send buffers over a certain fixed size.
const ITER_CHUNK_SIZE: usize = 64 * 1024;

if self.scratch_space.len() > ITER_CHUNK_SIZE {
// We intentionally clone here so that our scratch space is not
// recreated with zero capacity (via `Vec::new`), but instead can
// be `.clear()`ed in-place and reused.
Expand All @@ -63,22 +67,11 @@ impl ChunkedWriter {
}
}

/// Similar to [`Self::force_flush`], but only flushes if the data in the
/// scratch space is larger than our chunking threshold.
pub fn flush(&mut self) {
// For now, just send buffers over a certain fixed size.
const ITER_CHUNK_SIZE: usize = 64 * 1024;

if self.scratch_space.len() > ITER_CHUNK_SIZE {
self.force_flush();
}
}

/// Finalises the writer and returns all the chunks.
pub fn into_chunks(mut self) -> Vec<Box<[u8]>> {
if !self.scratch_space.is_empty() {
// This is equivalent to calling `force_flush`, but we avoid extra
// clone by just shrinking and pushing the scratch space in-place.
// Avoid extra clone by just shrinking and pushing the scratch space
// in-place.
self.chunks.push(self.scratch_space.into());
}
self.chunks
Expand Down Expand Up @@ -380,10 +373,6 @@ impl InstanceEnv {
let stdb = &*self.dbic.relational_db;
let tx = &mut *self.tx.get()?;

stdb.row_schema_for_table(tx, table_id)?.encode(&mut chunked_writer);
// initial chunk is expected to be schema itself, so force-flush it as a separate chunk
chunked_writer.force_flush();

for row in stdb.iter(tx, table_id)? {
row.view().encode(&mut chunked_writer);
// Flush at row boundaries.
Expand Down Expand Up @@ -424,18 +413,12 @@ impl InstanceEnv {
}
}

let mut chunked_writer = ChunkedWriter::default();

let stdb = &self.dbic.relational_db;
let tx = &mut *self.tx.get()?;

let schema = stdb.schema_for_table(tx, table_id)?;
let row_type = ProductType::from(&*schema);

// write and force flush schema as it's expected to be the first individual chunk
row_type.encode(&mut chunked_writer);
chunked_writer.force_flush();

let filter = filter::Expr::from_bytes(
// TODO: looks like module typespace is currently not hooked up to instances;
// use empty typespace for now which should be enough for primitives
Expand All @@ -453,6 +436,8 @@ impl InstanceEnv {
_ => unreachable!("query should always return a table"),
};

let mut chunked_writer = ChunkedWriter::default();

// write all rows and flush at row boundaries
for row in results.data {
row.data.encode(&mut chunked_writer);
Expand Down
4 changes: 2 additions & 2 deletions crates/core/src/host/wasmer/wasmer_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ impl WasmerModule {
WasmerModule { module, engine }
}

pub const IMPLEMENTED_ABI: abi::VersionTuple = abi::VersionTuple::new(6, 0);
pub const IMPLEMENTED_ABI: abi::VersionTuple = abi::VersionTuple::new(7, 0);

fn imports(&self, store: &mut Store, env: &FunctionEnv<WasmInstanceEnv>) -> Imports {
#[allow(clippy::assertions_on_constants)]
const _: () = assert!(WasmerModule::IMPLEMENTED_ABI.major == spacetimedb_lib::MODULE_ABI_MAJOR_VERSION);
imports! {
"spacetime_6.0" => {
"spacetime_7.0" => {
"_schedule_reducer" => Function::new_typed_with_env(store, env, WasmInstanceEnv::schedule_reducer),
"_cancel_reducer" => Function::new_typed_with_env(store, env, WasmInstanceEnv::cancel_reducer),
"_delete_by_col_eq" => Function::new_typed_with_env(
Expand Down
2 changes: 1 addition & 1 deletion crates/lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub use type_value::{AlgebraicValue, ProductValue};

pub use spacetimedb_sats as sats;

pub const MODULE_ABI_MAJOR_VERSION: u16 = 6;
pub const MODULE_ABI_MAJOR_VERSION: u16 = 7;

// if it ends up we need more fields in the future, we can split one of them in two
#[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Debug)]
Expand Down

1 comment on commit 469dff6

@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 💿 467.9±4.62ns 463.5±1.33ns - -
sqlite 🧠 464.5±5.44ns 448.3±2.13ns - -
stdb_module 💿 15.7±0.46µs 15.4±0.42µs - -
stdb_module 🧠 16.1±0.39µs 15.9±0.36µs - -
stdb_raw 💿 101.5±0.30ns 103.5±0.20ns - -
stdb_raw 🧠 101.9±0.44ns 103.4±0.34ns - -

Single-row insertions

db on disk schema index type load new latency old latency new throughput old throughput
sqlite 💿 location multi_index 0 14.9±1.60µs 14.9±0.79µs 65.6 Ktx/sec 65.4 Ktx/sec
sqlite 💿 location multi_index 1000 15.8±0.14µs 15.9±0.17µs 61.7 Ktx/sec 61.6 Ktx/sec
sqlite 💿 location non_unique 0 7.3±1.39µs 7.2±0.03µs 133.0 Ktx/sec 136.0 Ktx/sec
sqlite 💿 location non_unique 1000 7.1±0.04µs 7.1±0.04µs 136.9 Ktx/sec 138.4 Ktx/sec
sqlite 💿 location unique 0 7.3±0.98µs 7.2±0.35µs 133.7 Ktx/sec 136.1 Ktx/sec
sqlite 💿 location unique 1000 7.2±0.05µs 7.1±0.03µs 136.5 Ktx/sec 137.6 Ktx/sec
sqlite 💿 person multi_index 0 14.8±3.01µs 14.7±1.52µs 65.8 Ktx/sec 66.3 Ktx/sec
sqlite 💿 person multi_index 1000 16.2±0.11µs 16.3±0.10µs 60.3 Ktx/sec 60.1 Ktx/sec
sqlite 💿 person non_unique 0 7.5±2.20µs 7.3±1.22µs 130.8 Ktx/sec 133.8 Ktx/sec
sqlite 💿 person non_unique 1000 7.4±0.14µs 7.3±0.06µs 132.8 Ktx/sec 133.6 Ktx/sec
sqlite 💿 person unique 0 7.3±0.66µs 7.1±0.04µs 133.1 Ktx/sec 137.1 Ktx/sec
sqlite 💿 person unique 1000 7.3±0.05µs 7.3±0.06µs 133.4 Ktx/sec 134.7 Ktx/sec
sqlite 🧠 location multi_index 0 4.1±0.02µs 4.1±0.01µs 235.8 Ktx/sec 238.6 Ktx/sec
sqlite 🧠 location multi_index 1000 5.4±0.04µs 5.4±0.02µs 181.4 Ktx/sec 181.0 Ktx/sec
sqlite 🧠 location non_unique 0 1903.7±7.33ns 1907.3±3.98ns 513.0 Ktx/sec 512.0 Ktx/sec
sqlite 🧠 location non_unique 1000 1934.3±11.74ns 1925.3±12.90ns 504.9 Ktx/sec 507.2 Ktx/sec
sqlite 🧠 location unique 0 1873.4±17.71ns 1876.8±5.54ns 521.3 Ktx/sec 520.3 Ktx/sec
sqlite 🧠 location unique 1000 1991.1±11.92ns 1970.8±11.24ns 490.5 Ktx/sec 495.5 Ktx/sec
sqlite 🧠 person multi_index 0 4.0±0.01µs 4.0±0.02µs 246.0 Ktx/sec 245.2 Ktx/sec
sqlite 🧠 person multi_index 1000 5.9±0.03µs 5.8±0.24µs 166.3 Ktx/sec 168.3 Ktx/sec
sqlite 🧠 person non_unique 0 1988.2±9.62ns 1977.6±10.14ns 491.2 Ktx/sec 493.8 Ktx/sec
sqlite 🧠 person non_unique 1000 2.1±0.01µs 2.1±0.02µs 464.5 Ktx/sec 476.2 Ktx/sec
sqlite 🧠 person unique 0 1980.7±7.37ns 1954.7±8.27ns 493.0 Ktx/sec 499.6 Ktx/sec
sqlite 🧠 person unique 1000 2.1±0.03µs 2.1±0.04µs 455.2 Ktx/sec 466.8 Ktx/sec
stdb_module 💿 location multi_index 0 40.4±5.59µs 33.7±2.98µs 24.2 Ktx/sec 28.9 Ktx/sec
stdb_module 💿 location multi_index 1000 453.0±26.08µs 266.8±24.18µs 2.2 Ktx/sec 3.7 Ktx/sec
stdb_module 💿 location non_unique 0 34.9±3.94µs 34.2±3.88µs 28.0 Ktx/sec 28.5 Ktx/sec
stdb_module 💿 location non_unique 1000 227.6±16.99µs 270.6±79.29µs 4.3 Ktx/sec 3.6 Ktx/sec
stdb_module 💿 location unique 0 36.5±3.37µs 37.1±3.47µs 26.7 Ktx/sec 26.4 Ktx/sec
stdb_module 💿 location unique 1000 394.8±111.02µs 229.6±8.75µs 2.5 Ktx/sec 4.3 Ktx/sec
stdb_module 💿 person multi_index 0 53.2±4.13µs 47.4±12.19µs 18.4 Ktx/sec 20.6 Ktx/sec
stdb_module 💿 person multi_index 1000 355.7±40.34µs 590.8±38.97µs 2.7 Ktx/sec 1692 tx/sec
stdb_module 💿 person non_unique 0 38.2±3.94µs 35.7±4.73µs 25.6 Ktx/sec 27.3 Ktx/sec
stdb_module 💿 person non_unique 1000 273.2±6.84µs 230.6±5.56µs 3.6 Ktx/sec 4.2 Ktx/sec
stdb_module 💿 person unique 0 43.7±5.05µs 38.6±4.04µs 22.4 Ktx/sec 25.3 Ktx/sec
stdb_module 💿 person unique 1000 442.6±9.47µs 563.0±437.57µs 2.2 Ktx/sec 1776 tx/sec
stdb_module 🧠 location multi_index 0 30.3±2.59µs 27.5±2.19µs 32.2 Ktx/sec 35.5 Ktx/sec
stdb_module 🧠 location multi_index 1000 204.0±19.65µs 235.1±82.62µs 4.8 Ktx/sec 4.2 Ktx/sec
stdb_module 🧠 location non_unique 0 25.5±1.77µs 26.3±1.58µs 38.3 Ktx/sec 37.2 Ktx/sec
stdb_module 🧠 location non_unique 1000 204.2±18.23µs 230.2±24.41µs 4.8 Ktx/sec 4.2 Ktx/sec
stdb_module 🧠 location unique 0 28.1±2.21µs 26.4±2.39µs 34.8 Ktx/sec 37.0 Ktx/sec
stdb_module 🧠 location unique 1000 227.1±50.52µs 179.1±4.41µs 4.3 Ktx/sec 5.5 Ktx/sec
stdb_module 🧠 person multi_index 0 37.8±3.68µs 38.7±4.42µs 25.8 Ktx/sec 25.2 Ktx/sec
stdb_module 🧠 person multi_index 1000 200.0±82.55µs 439.4±68.62µs 4.9 Ktx/sec 2.2 Ktx/sec
stdb_module 🧠 person non_unique 0 26.6±1.80µs 27.4±2.28µs 36.7 Ktx/sec 35.6 Ktx/sec
stdb_module 🧠 person non_unique 1000 227.2±80.99µs 219.5±22.95µs 4.3 Ktx/sec 4.4 Ktx/sec
stdb_module 🧠 person unique 0 33.6±3.39µs 31.1±2.33µs 29.1 Ktx/sec 31.4 Ktx/sec
stdb_module 🧠 person unique 1000 263.7±77.72µs 359.6±54.95µs 3.7 Ktx/sec 2.7 Ktx/sec
stdb_raw 💿 location multi_index 0 5.4±0.42µs 5.4±0.01µs 181.5 Ktx/sec 181.9 Ktx/sec
stdb_raw 💿 location multi_index 1000 41.6±77.10µs 33.5±0.63µs 23.5 Ktx/sec 29.2 Ktx/sec
stdb_raw 💿 location non_unique 0 3.6±0.01µs 3.6±0.01µs 273.9 Ktx/sec 274.5 Ktx/sec
stdb_raw 💿 location non_unique 1000 21.6±0.29µs 21.7±0.20µs 45.2 Ktx/sec 45.0 Ktx/sec
stdb_raw 💿 location unique 0 4.3±0.04µs 4.3±0.02µs 225.4 Ktx/sec 225.4 Ktx/sec
stdb_raw 💿 location unique 1000 43.0±160.33µs 26.9±0.24µs 22.7 Ktx/sec 36.3 Ktx/sec
stdb_raw 💿 person multi_index 0 9.1±0.29µs 9.1±0.04µs 107.6 Ktx/sec 107.5 Ktx/sec
stdb_raw 💿 person multi_index 1000 60.1±351.94µs 72.2±478.84µs 16.2 Ktx/sec 13.5 Ktx/sec
stdb_raw 💿 person non_unique 0 4.2±0.01µs 4.2±0.01µs 235.1 Ktx/sec 235.2 Ktx/sec
stdb_raw 💿 person non_unique 1000 29.6±153.29µs 14.2±0.11µs 33.0 Ktx/sec 68.7 Ktx/sec
stdb_raw 💿 person unique 0 5.9±0.01µs 6.0±0.01µs 165.7 Ktx/sec 162.6 Ktx/sec
stdb_raw 💿 person unique 1000 21.9±0.31µs 21.7±0.44µs 44.6 Ktx/sec 45.0 Ktx/sec
stdb_raw 🧠 location multi_index 0 4.2±0.01µs 4.1±0.01µs 230.9 Ktx/sec 235.7 Ktx/sec
stdb_raw 🧠 location multi_index 1000 30.0±0.69µs 29.2±0.60µs 32.6 Ktx/sec 33.4 Ktx/sec
stdb_raw 🧠 location non_unique 0 2.3±0.01µs 2.3±0.01µs 427.4 Ktx/sec 432.6 Ktx/sec
stdb_raw 🧠 location non_unique 1000 19.7±0.07µs 20.2±0.06µs 49.5 Ktx/sec 48.3 Ktx/sec
stdb_raw 🧠 location unique 0 3.1±0.01µs 3.0±0.01µs 312.6 Ktx/sec 321.7 Ktx/sec
stdb_raw 🧠 location unique 1000 24.6±0.17µs 25.1±0.14µs 39.8 Ktx/sec 39.0 Ktx/sec
stdb_raw 🧠 person multi_index 0 7.7±0.01µs 7.6±0.03µs 126.5 Ktx/sec 127.8 Ktx/sec
stdb_raw 🧠 person multi_index 1000 21.9±1.27µs 22.3±1.16µs 44.7 Ktx/sec 43.8 Ktx/sec
stdb_raw 🧠 person non_unique 0 2.9±0.01µs 2.8±0.00µs 338.1 Ktx/sec 346.7 Ktx/sec
stdb_raw 🧠 person non_unique 1000 12.9±0.17µs 13.2±0.16µs 75.7 Ktx/sec 74.0 Ktx/sec
stdb_raw 🧠 person unique 0 4.7±0.05µs 4.6±0.04µs 208.3 Ktx/sec 212.2 Ktx/sec
stdb_raw 🧠 person unique 1000 17.4±0.65µs 17.9±0.51µs 56.0 Ktx/sec 54.6 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 131.1±0.47µs 132.1±3.29µs 7.5 Ktx/sec 7.4 Ktx/sec
sqlite 💿 location multi_index 1000 100 202.3±1.17µs 207.5±36.66µs 4.8 Ktx/sec 4.7 Ktx/sec
sqlite 💿 location non_unique 0 100 51.1±1.01µs 51.3±2.12µs 19.1 Ktx/sec 19.0 Ktx/sec
sqlite 💿 location non_unique 1000 100 53.4±0.27µs 54.2±0.29µs 18.3 Ktx/sec 18.0 Ktx/sec
sqlite 💿 location unique 0 100 52.9±1.16µs 52.8±1.88µs 18.5 Ktx/sec 18.5 Ktx/sec
sqlite 💿 location unique 1000 100 56.0±0.55µs 57.9±0.30µs 17.4 Ktx/sec 16.9 Ktx/sec
sqlite 💿 person multi_index 0 100 120.4±5.79µs 117.7±0.34µs 8.1 Ktx/sec 8.3 Ktx/sec
sqlite 💿 person multi_index 1000 100 237.1±22.66µs 235.3±4.81µs 4.1 Ktx/sec 4.1 Ktx/sec
sqlite 💿 person non_unique 0 100 51.2±1.63µs 49.3±1.30µs 19.1 Ktx/sec 19.8 Ktx/sec
sqlite 💿 person non_unique 1000 100 62.1±0.22µs 60.7±0.28µs 15.7 Ktx/sec 16.1 Ktx/sec
sqlite 💿 person unique 0 100 52.1±1.26µs 51.6±1.24µs 18.8 Ktx/sec 18.9 Ktx/sec
sqlite 💿 person unique 1000 100 56.7±0.23µs 57.2±0.30µs 17.2 Ktx/sec 17.1 Ktx/sec
sqlite 🧠 location multi_index 0 100 120.0±0.36µs 120.3±0.35µs 8.1 Ktx/sec 8.1 Ktx/sec
sqlite 🧠 location multi_index 1000 100 170.6±0.48µs 170.7±0.66µs 5.7 Ktx/sec 5.7 Ktx/sec
sqlite 🧠 location non_unique 0 100 43.9±0.49µs 43.6±0.36µs 22.3 Ktx/sec 22.4 Ktx/sec
sqlite 🧠 location non_unique 1000 100 45.1±0.27µs 45.3±0.34µs 21.7 Ktx/sec 21.6 Ktx/sec
sqlite 🧠 location unique 0 100 45.0±0.33µs 45.2±0.31µs 21.7 Ktx/sec 21.6 Ktx/sec
sqlite 🧠 location unique 1000 100 48.5±0.39µs 50.0±0.28µs 20.1 Ktx/sec 19.5 Ktx/sec
sqlite 🧠 person multi_index 0 100 108.6±0.38µs 107.6±0.50µs 9.0 Ktx/sec 9.1 Ktx/sec
sqlite 🧠 person multi_index 1000 100 191.1±0.37µs 191.8±0.30µs 5.1 Ktx/sec 5.1 Ktx/sec
sqlite 🧠 person non_unique 0 100 44.5±0.27µs 43.2±0.27µs 21.9 Ktx/sec 22.6 Ktx/sec
sqlite 🧠 person non_unique 1000 100 48.7±0.16µs 47.0±0.30µs 20.1 Ktx/sec 20.8 Ktx/sec
sqlite 🧠 person unique 0 100 46.2±0.37µs 44.9±0.36µs 21.1 Ktx/sec 21.7 Ktx/sec
sqlite 🧠 person unique 1000 100 49.8±0.26µs 49.2±0.20µs 19.6 Ktx/sec 19.9 Ktx/sec
stdb_module 💿 location multi_index 0 100 849.8±25.77µs 553.8±6.13µs 1176 tx/sec 1805 tx/sec
stdb_module 💿 location multi_index 1000 100 887.9±106.13µs 1036.1±168.90µs 1126 tx/sec 965 tx/sec
stdb_module 💿 location non_unique 0 100 513.0±16.22µs 479.4±51.11µs 1949 tx/sec 2.0 Ktx/sec
stdb_module 💿 location non_unique 1000 100 700.1±16.09µs 692.0±33.01µs 1428 tx/sec 1445 tx/sec
stdb_module 💿 location unique 0 100 680.1±6.73µs 534.3±86.40µs 1470 tx/sec 1871 tx/sec
stdb_module 💿 location unique 1000 100 941.0±7.75µs 816.1±84.57µs 1062 tx/sec 1225 tx/sec
stdb_module 💿 person multi_index 0 100 1403.1±10.82µs 922.7±3.48µs 712 tx/sec 1083 tx/sec
stdb_module 💿 person multi_index 1000 100 1063.8±67.89µs 1917.6±71.56µs 940 tx/sec 521 tx/sec
stdb_module 💿 person non_unique 0 100 690.4±6.50µs 658.3±2.49µs 1448 tx/sec 1519 tx/sec
stdb_module 💿 person non_unique 1000 100 890.8±20.79µs 1053.5±32.56µs 1122 tx/sec 949 tx/sec
stdb_module 💿 person unique 0 100 787.4±33.43µs 944.9±4.85µs 1270 tx/sec 1058 tx/sec
stdb_module 💿 person unique 1000 100 1145.2±92.51µs 1360.0±95.82µs 873 tx/sec 735 tx/sec
stdb_module 🧠 location multi_index 0 100 632.8±65.24µs 647.1±73.27µs 1580 tx/sec 1545 tx/sec
stdb_module 🧠 location multi_index 1000 100 933.2±7.92µs 868.1±81.52µs 1071 tx/sec 1151 tx/sec
stdb_module 🧠 location non_unique 0 100 396.2±20.58µs 383.3±18.34µs 2.5 Ktx/sec 2.5 Ktx/sec
stdb_module 🧠 location non_unique 1000 100 574.1±13.88µs 596.1±44.64µs 1741 tx/sec 1677 tx/sec
stdb_module 🧠 location unique 0 100 502.3±42.75µs 558.6±48.00µs 1990 tx/sec 1790 tx/sec
stdb_module 🧠 location unique 1000 100 748.7±18.87µs 748.6±9.22µs 1335 tx/sec 1335 tx/sec
stdb_module 🧠 person multi_index 0 100 1007.8±229.24µs 947.7±14.55µs 992 tx/sec 1055 tx/sec
stdb_module 🧠 person multi_index 1000 100 1367.2±33.61µs 1315.7±54.64µs 731 tx/sec 760 tx/sec
stdb_module 🧠 person non_unique 0 100 623.3±35.28µs 602.9±18.91µs 1604 tx/sec 1658 tx/sec
stdb_module 🧠 person non_unique 1000 100 818.4±61.58µs 766.2±40.18µs 1221 tx/sec 1305 tx/sec
stdb_module 🧠 person unique 0 100 822.2±106.07µs 744.9±156.88µs 1216 tx/sec 1342 tx/sec
stdb_module 🧠 person unique 1000 100 1087.8±14.09µs 1337.0±17.00µs 919 tx/sec 747 tx/sec
stdb_raw 💿 location multi_index 0 100 318.5±10.81µs 320.8±15.16µs 3.1 Ktx/sec 3.0 Ktx/sec
stdb_raw 💿 location multi_index 1000 100 393.2±230.13µs 380.3±80.53µs 2.5 Ktx/sec 2.6 Ktx/sec
stdb_raw 💿 location non_unique 0 100 142.8±4.46µs 144.6±0.36µs 6.8 Ktx/sec 6.8 Ktx/sec
stdb_raw 💿 location non_unique 1000 100 174.1±89.39µs 166.0±0.99µs 5.6 Ktx/sec 5.9 Ktx/sec
stdb_raw 💿 location unique 0 100 221.8±4.41µs 222.8±0.26µs 4.4 Ktx/sec 4.4 Ktx/sec
stdb_raw 💿 location unique 1000 100 281.5±127.75µs 290.4±208.89µs 3.5 Ktx/sec 3.4 Ktx/sec
stdb_raw 💿 person multi_index 0 100 663.9±1.54µs 660.6±20.12µs 1506 tx/sec 1513 tx/sec
stdb_raw 💿 person multi_index 1000 100 766.7±419.96µs 750.1±304.57µs 1304 tx/sec 1333 tx/sec
stdb_raw 💿 person non_unique 0 100 200.2±9.76µs 202.2±13.47µs 4.9 Ktx/sec 4.8 Ktx/sec
stdb_raw 💿 person non_unique 1000 100 239.9±181.92µs 223.4±0.71µs 4.1 Ktx/sec 4.4 Ktx/sec
stdb_raw 💿 person unique 0 100 367.4±0.82µs 365.6±0.68µs 2.7 Ktx/sec 2.7 Ktx/sec
stdb_raw 💿 person unique 1000 100 408.7±1.02µs 410.7±6.58µs 2.4 Ktx/sec 2.4 Ktx/sec
stdb_raw 🧠 location multi_index 0 100 320.3±0.30µs 320.8±0.42µs 3.0 Ktx/sec 3.0 Ktx/sec
stdb_raw 🧠 location multi_index 1000 100 366.0±0.48µs 368.0±0.57µs 2.7 Ktx/sec 2.7 Ktx/sec
stdb_raw 🧠 location non_unique 0 100 138.6±0.26µs 140.3±0.22µs 7.0 Ktx/sec 7.0 Ktx/sec
stdb_raw 🧠 location non_unique 1000 100 160.6±0.49µs 163.4±0.17µs 6.1 Ktx/sec 6.0 Ktx/sec
stdb_raw 🧠 location unique 0 100 218.1±0.49µs 221.4±1.28µs 4.5 Ktx/sec 4.4 Ktx/sec
stdb_raw 🧠 location unique 1000 100 263.6±0.86µs 267.0±0.70µs 3.7 Ktx/sec 3.7 Ktx/sec
stdb_raw 🧠 person multi_index 0 100 654.0±0.81µs 651.5±0.37µs 1528 tx/sec 1535 tx/sec
stdb_raw 🧠 person multi_index 1000 100 705.5±1.66µs 706.8±1.62µs 1417 tx/sec 1414 tx/sec
stdb_raw 🧠 person non_unique 0 100 196.6±0.21µs 199.8±0.54µs 5.0 Ktx/sec 4.9 Ktx/sec
stdb_raw 🧠 person non_unique 1000 100 217.9±0.89µs 223.2±0.94µs 4.5 Ktx/sec 4.4 Ktx/sec
stdb_raw 🧠 person unique 0 100 364.3±0.37µs 363.8±0.31µs 2.7 Ktx/sec 2.7 Ktx/sec
stdb_raw 🧠 person unique 1000 100 406.6±0.90µs 406.4±0.71µs 2.4 Ktx/sec 2.4 Ktx/sec

Full table iterate

db on disk schema index type new latency old latency new throughput old throughput
sqlite 💿 location unique 9.0±0.08µs 8.9±0.10µs 108.5 Ktx/sec 109.5 Ktx/sec
sqlite 💿 person unique 9.3±0.11µs 9.4±0.08µs 105.0 Ktx/sec 103.5 Ktx/sec
sqlite 🧠 location unique 7.8±0.10µs 8.0±0.09µs 125.6 Ktx/sec 122.2 Ktx/sec
sqlite 🧠 person unique 8.2±0.10µs 8.3±0.11µs 118.9 Ktx/sec 118.2 Ktx/sec
stdb_module 💿 location unique 46.6±5.93µs 44.6±4.13µs 21.0 Ktx/sec 21.9 Ktx/sec
stdb_module 💿 person unique 60.9±11.30µs 58.8±9.47µs 16.0 Ktx/sec 16.6 Ktx/sec
stdb_module 🧠 location unique 46.2±5.06µs 45.2±3.32µs 21.1 Ktx/sec 21.6 Ktx/sec
stdb_module 🧠 person unique 70.2±6.10µs 58.4±9.62µs 13.9 Ktx/sec 16.7 Ktx/sec
stdb_raw 💿 location unique 8.5±0.02µs 9.6±0.01µs 115.2 Ktx/sec 102.1 Ktx/sec
stdb_raw 💿 person unique 10.7±0.12µs 11.6±0.02µs 91.2 Ktx/sec 84.5 Ktx/sec
stdb_raw 🧠 location unique 8.5±0.02µs 9.5±0.12µs 115.3 Ktx/sec 102.9 Ktx/sec
stdb_raw 🧠 person unique 10.7±0.02µs 11.6±0.01µs 91.4 Ktx/sec 84.5 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.00µs 2.4±0.01µs 409.4 Ktx/sec 412.2 Ktx/sec
sqlite 🧠 u32 1000 1161.9±4.78ns 1171.8±6.06ns 840.5 Ktx/sec 833.4 Ktx/sec
stdb_module 💿 u32 1000 18.1±0.93µs 17.9±1.13µs 54.0 Ktx/sec 54.5 Ktx/sec
stdb_module 🧠 u32 1000 18.4±1.22µs 17.5±0.68µs 53.1 Ktx/sec 55.7 Ktx/sec
stdb_raw 💿 u32 1000 492.2±0.87ns 487.4±0.76ns 1984.3 Ktx/sec 2003.5 Ktx/sec
stdb_raw 🧠 u32 1000 494.8±1.33ns 486.1±0.66ns 1973.7 Ktx/sec 2008.8 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.8±0.02µs 5.8±0.01µs 168.0 Ktx/sec 167.2 Ktx/sec
sqlite 💿 string non_indexed 1000 10 50.4±0.67µs 51.0±0.78µs 19.4 Ktx/sec 19.2 Ktx/sec
sqlite 💿 u64 indexed 1000 10 5.5±0.02µs 5.6±0.03µs 176.0 Ktx/sec 173.6 Ktx/sec
sqlite 💿 u64 non_indexed 1000 10 33.1±0.30µs 32.9±0.21µs 29.5 Ktx/sec 29.7 Ktx/sec
sqlite 🧠 string indexed 1000 10 4.3±0.01µs 4.4±0.01µs 226.0 Ktx/sec 222.1 Ktx/sec
sqlite 🧠 string non_indexed 1000 10 47.9±0.25µs 49.1±0.98µs 20.4 Ktx/sec 19.9 Ktx/sec
sqlite 🧠 u64 indexed 1000 10 4.1±0.01µs 4.2±0.01µs 240.1 Ktx/sec 233.8 Ktx/sec
sqlite 🧠 u64 non_indexed 1000 10 31.7±0.16µs 31.8±0.19µs 30.8 Ktx/sec 30.7 Ktx/sec
stdb_module 💿 string indexed 1000 10 27.3±2.49µs 25.0±1.91µs 35.7 Ktx/sec 39.1 Ktx/sec
stdb_module 💿 string non_indexed 1000 10 175.4±1.90µs 213.3±43.47µs 5.6 Ktx/sec 4.6 Ktx/sec
stdb_module 💿 u64 indexed 1000 10 21.5±1.59µs 22.2±3.06µs 45.4 Ktx/sec 44.0 Ktx/sec
stdb_module 💿 u64 non_indexed 1000 10 138.0±1.51µs 163.0±3.97µs 7.1 Ktx/sec 6.0 Ktx/sec
stdb_module 🧠 string indexed 1000 10 24.1±1.96µs 25.8±2.10µs 40.5 Ktx/sec 37.8 Ktx/sec
stdb_module 🧠 string non_indexed 1000 10 171.3±1.92µs 188.2±0.60µs 5.7 Ktx/sec 5.2 Ktx/sec
stdb_module 🧠 u64 indexed 1000 10 20.6±0.73µs 20.9±1.33µs 47.5 Ktx/sec 46.7 Ktx/sec
stdb_module 🧠 u64 non_indexed 1000 10 135.5±0.96µs 162.8±6.52µs 7.2 Ktx/sec 6.0 Ktx/sec
stdb_raw 💿 string indexed 1000 10 2.6±0.01µs 2.5±0.02µs 369.9 Ktx/sec 385.0 Ktx/sec
stdb_raw 💿 string non_indexed 1000 10 180.4±1.73µs 184.3±0.20µs 5.4 Ktx/sec 5.3 Ktx/sec
stdb_raw 💿 u64 indexed 1000 10 2.1±0.01µs 2.2±0.01µs 456.2 Ktx/sec 451.8 Ktx/sec
stdb_raw 💿 u64 non_indexed 1000 10 142.0±0.11µs 139.9±0.42µs 6.9 Ktx/sec 7.0 Ktx/sec
stdb_raw 🧠 string indexed 1000 10 2.7±0.00µs 2.6±0.00µs 367.8 Ktx/sec 382.4 Ktx/sec
stdb_raw 🧠 string non_indexed 1000 10 182.8±0.32µs 184.8±0.23µs 5.3 Ktx/sec 5.3 Ktx/sec
stdb_raw 🧠 u64 indexed 1000 10 2.2±0.01µs 2.2±0.00µs 453.9 Ktx/sec 452.0 Ktx/sec
stdb_raw 🧠 u64 non_indexed 1000 10 142.1±0.39µs 140.1±0.26µs 6.9 Ktx/sec 7.0 Ktx/sec

Serialize

schema format count new latency old latency new throughput old throughput
location bsatn 100 1782.2±28.72ns 1722.5±34.58ns 53.5 Mtx/sec 55.4 Mtx/sec
location json 100 3.7±0.04µs 3.1±0.01µs 26.0 Mtx/sec 30.4 Mtx/sec
location product_value 100 2.4±0.01µs 2.4±0.01µs 39.4 Mtx/sec 40.4 Mtx/sec
person bsatn 100 2.9±0.01µs 2.5±0.02µs 32.6 Mtx/sec 38.3 Mtx/sec
person json 100 5.3±0.07µs 4.8±0.02µs 18.1 Mtx/sec 19.8 Mtx/sec
person product_value 100 1616.4±13.48ns 1618.0±22.21ns 59.0 Mtx/sec 58.9 Mtx/sec

Module: invoke with large arguments

arg size new latency old latency new throughput old throughput
64KiB 79.6±4.97µs 80.5±12.32µs - -

Module: print bulk

line count new latency old latency new throughput old throughput
1 20.3±0.94µs 19.8±1.22µs - -
100 202.1±1.65µs 204.5±11.21µs - -
1000 1890.2±58.15µs 1891.9±64.32µs - -

Remaining benchmarks

name new latency old latency new throughput old throughput

Please sign in to comment.