From 1fa6346629ef6d4d46398efd0aa593284a692987 Mon Sep 17 00:00:00 2001 From: Navya Date: Wed, 11 Feb 2026 14:44:50 +0530 Subject: [PATCH 1/3] feat: implement DROP TABLE and verify storage wipe logic --- nexum_core/src/executor/mod.rs | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/nexum_core/src/executor/mod.rs b/nexum_core/src/executor/mod.rs index aba2497..29adc09 100644 --- a/nexum_core/src/executor/mod.rs +++ b/nexum_core/src/executor/mod.rs @@ -818,6 +818,60 @@ mod tests { use super::*; use crate::sql::types::{Column, DataType, SelectItem}; + //added a test that checks if dropping a non-existent table without IF EXISTS fails correctly. + #[test] + fn test_drop_non_existent_table_fails() { + let storage = StorageEngine::memory().unwrap(); + let executor = Executor::new(storage); + + let drop = Statement::DropTable { + name: "imaginary_table".to_string(), + if_exists: false, + }; + + let result = executor.execute(drop); + assert!(result.is_err(), "Dropping a non-existent table should return an error"); + } + + //second test + #[test] + fn test_verify_physical_deletion() { + // 1. Setup Engine + let storage = StorageEngine::memory().unwrap(); + let executor = Executor::new(storage.clone()); + let table_name = "cleanup_test"; + + // 2. Create and Insert Data + let create = Statement::CreateTable { + name: table_name.to_string(), + columns: vec![Column { name: "id".to_string(), data_type: DataType::Integer }], + }; + executor.execute(create).unwrap(); + + let insert = Statement::Insert { + table: table_name.to_string(), + columns: vec!["id".to_string()], + values: vec![vec![Value::Integer(1)], vec![Value::Integer(2)]], + }; + executor.execute(insert).unwrap(); + + // 3. Verify data exists in raw storage before DROP + let prefix = format!("data:{}:", table_name).into_bytes(); + let rows_before = storage.scan_prefix(&prefix).unwrap(); + assert_eq!(rows_before.len(), 2, "Data should exist before DROP"); + + // 4. Execute DROP + let drop = Statement::DropTable { + name: table_name.to_string(), + if_exists: false, + }; + executor.execute(drop).unwrap(); + + // 5. THE CRITICAL CHECK: Scan raw storage again + let rows_after = storage.scan_prefix(&prefix).unwrap(); + assert_eq!(rows_after.len(), 0, "PHYSICAL WIPE FAILED: Raw data still exists in storage after DROP!"); + } + #[test] fn test_end_to_end_execution() { let storage = StorageEngine::memory().unwrap(); From a820d1349a4d9961026917dc81470841aae19a88 Mon Sep 17 00:00:00 2001 From: Navya Date: Wed, 11 Feb 2026 18:07:11 +0530 Subject: [PATCH 2/3] feat: add nexum vs sqlite benchmark suite and documentation --- Cargo.lock | 85 ++++++++++++++++++++++++ nexum_core/Cargo.toml | 5 ++ nexum_core/benches/README.md | 45 ++++++++++++- nexum_core/benches/bench_results.png | Bin 0 -> 21084 bytes nexum_core/benches/db_comparison.rs | 94 +++++++++++++++++++++++++++ nexum_core/benches/storage_bench.rs | 3 + nexum_core/benches/visualize.py | 27 ++++++++ nexum_core/src/storage/mod.rs | 7 +- 8 files changed, 262 insertions(+), 4 deletions(-) create mode 100644 nexum_core/benches/bench_results.png create mode 100644 nexum_core/benches/db_comparison.rs create mode 100644 nexum_core/benches/visualize.py diff --git a/Cargo.lock b/Cargo.lock index a0c327b..46fbf5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,18 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.4" @@ -221,6 +233,18 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fastrand" version = "2.3.0" @@ -269,6 +293,24 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashlink" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" +dependencies = [ + "hashbrown", +] + [[package]] name = "heck" version = "0.5.0" @@ -348,6 +390,16 @@ version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" +[[package]] +name = "libsqlite3-sys" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f" +dependencies = [ + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.11.0" @@ -413,6 +465,7 @@ dependencies = [ "log", "pyo3", "regex", + "rusqlite", "serde", "serde_json", "sled", @@ -496,6 +549,12 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + [[package]] name = "plotters" version = "0.3.7" @@ -684,6 +743,20 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +[[package]] +name = "rusqlite" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae" +dependencies = [ + "bitflags 2.10.0", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + [[package]] name = "rustix" version = "1.1.3" @@ -911,6 +984,18 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "walkdir" version = "2.5.0" diff --git a/nexum_core/Cargo.toml b/nexum_core/Cargo.toml index 8abe1b8..9a9d82c 100644 --- a/nexum_core/Cargo.toml +++ b/nexum_core/Cargo.toml @@ -23,6 +23,11 @@ log = "0.4" [dev-dependencies] tempfile = "3.24" criterion = { version = "0.5", features = ["html_reports"] } +rusqlite = "0.31.0" # To interface with SQLite for comparison + +[[bench]] +name = "db_comparison" +harness = false [[bench]] name = "storage_bench" diff --git a/nexum_core/benches/README.md b/nexum_core/benches/README.md index b0bf921..b873087 100644 --- a/nexum_core/benches/README.md +++ b/nexum_core/benches/README.md @@ -3,8 +3,51 @@ This directory contains comprehensive performance benchmarks for the `nexum_core` module using the [Criterion](https://github.com/bheisler/criterion.rs) benchmarking framework. ## Benchmark Categories +## Performance & Benchmarks (Feb 2026) +To maintain the high performance expected of a Rust-based engine, NexumDB is continuously benchmarked against SQLite using the `criterion` suite. -### 1. Storage Engine Benchmarks (`storage_bench.rs`) +### Comparative Performance Results +| Operation | SQLite | NexumDB | Delta | +| :--- | :--- | :--- | :--- | +| **Single INSERT** | 15.18 ms | **7.48 ms** | NexumDB ~2x Faster | +| **Point SELECT (Cold)** | **140.5 µs** | 1.86 ms | SQLite Faster | +| **Point SELECT (Cached)**| **143.8 µs** | 1.87 ms | SQLite Faster | + +### Analysis +![Benchmark Visualization](./nexum_core/benches/bench_results.png) + +### Architectural Insights + +#### 1. Write Throughput: The LSM-Tree Advantage +NexumDB’s storage engine (`sled`) utilizes a **Log-Structured Merge-tree (LSM-tree)**, whereas SQLite uses a traditional **B-tree**. +* **LSM-tree (NexumDB):** Optimizes for writes by batching updates into immutable segments, leading to the 2x speedup observed in our `INSERT` benchmarks. +* **B-tree (SQLite):** Optimized for reads. Every write requires finding a leaf node on disk, which involves more synchronous I/O. + + + +#### 2. Read Latency & AI Overhead +In small-scale point lookups (1,000 rows), SQLite's raw C-speed is superior. NexumDB's current ~1.8ms latency includes: +* **SQL Parsing**: Converting strings to `Statement` enums. +* **PyO3 Bridge**: The overhead of crossing the Rust-Python boundary for AI-native planning. +* **Semantic Caching**: The current benchmark dataset is too small to show the "skip-the-disk" benefits of semantic caching, which scale exponentially with query complexity and data volume. + +--- + +## Architecture +* **Core System**: Rust-based storage engine using `sled`, with SQL parsing and intelligent execution. +* **AI Engine**: Python-based semantic caching, NL translation, and RL optimization via local models. +* **Integration**: PyO3 bindings for seamless Rust-Python interoperability. + + + +## Features +### v0.4.0 - Core Correctness & Table Management +* **Projection-Correct SELECT**: Column/alias projection with schema validation. +* **Schema-Safe Writes**: INSERT/UPDATE validation with best-effort coercion. +* **Table Management**: SHOW TABLES, DESCRIBE, DROP TABLE (IF EXISTS). +* **Performance Suite**: Integrated benchmark framework for regression testing. + +--- Tests the performance of the underlying storage engine operations: diff --git a/nexum_core/benches/bench_results.png b/nexum_core/benches/bench_results.png new file mode 100644 index 0000000000000000000000000000000000000000..6b04bd3f8583a793012b23ffddf09e4884f7798f GIT binary patch literal 21084 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 literal 0 HcmV?d00001 diff --git a/nexum_core/benches/db_comparison.rs b/nexum_core/benches/db_comparison.rs new file mode 100644 index 0000000..571fc80 --- /dev/null +++ b/nexum_core/benches/db_comparison.rs @@ -0,0 +1,94 @@ +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use rusqlite::Connection; +use tempfile::{NamedTempFile, tempdir}; + +use nexum_core::storage::StorageEngine; +use nexum_core::executor::Executor; +use nexum_core::sql::parser::Parser; + +fn setup_sqlite() -> Connection { + let db_file = NamedTempFile::new().unwrap(); + let conn = Connection::open(db_file.path()).unwrap(); + conn.execute("CREATE TABLE bench (id INTEGER PRIMARY KEY, val TEXT)", []).unwrap(); + conn +} + +fn setup_nexum() -> Executor { + let db_path = tempdir().unwrap(); + let storage = StorageEngine::new(db_path.path()).unwrap(); + let executor = Executor::new(storage); + + let sql = "CREATE TABLE bench (id INTEGER, val TEXT)"; + // Removed .remove(0) because parse returns a Statement directly + let statement = Parser::parse(sql).unwrap(); + executor.execute(statement).unwrap(); + + executor +} + +fn bench_inserts(c: &mut Criterion) { + let mut group = c.benchmark_group("Insert_Performance"); + + group.bench_function("SQLite_Single_Insert", |b| { + let conn = setup_sqlite(); + b.iter(|| { + conn.execute("INSERT INTO bench (val) VALUES ('test_data')", []).unwrap(); + }); + }); + + group.bench_function("NexumDB_Single_Insert", |b| { + let executor = setup_nexum(); + let sql = "INSERT INTO bench (id, val) VALUES (1, 'test_data')"; + let statement = Parser::parse(sql).unwrap(); + b.iter(|| { + executor.execute(statement.clone()).unwrap(); + }); + }); + + group.finish(); +} + +fn bench_selects(c: &mut Criterion) { + let mut group = c.benchmark_group("Select_Performance"); + let row_count = 1000; + + let sqlite_conn = setup_sqlite(); + for i in 0..row_count { + sqlite_conn.execute("INSERT INTO bench (id, val) VALUES (?1, 'data')", [i]).unwrap(); + } + + let nexum_executor = setup_nexum(); + let insert_sql = "INSERT INTO bench (id, val) VALUES (1, 'data')"; + let insert_stmt = Parser::parse(insert_sql).unwrap(); + for _ in 0..row_count { + nexum_executor.execute(insert_stmt.clone()).unwrap(); + } + + let select_sql = "SELECT val FROM bench WHERE id = 500"; + let select_stmt = Parser::parse(select_sql).unwrap(); + + group.bench_function("SQLite_Point_Lookup", |b| { + b.iter(|| { + let mut stmt = sqlite_conn.prepare("SELECT val FROM bench WHERE id = 500").unwrap(); + let _ = stmt.query_row([], |r| r.get::<_, String>(0)).unwrap(); + }); + }); + + group.bench_function("NexumDB_Point_Lookup_Cold", |b| { + b.iter(|| { + black_box(nexum_executor.execute(select_stmt.clone()).unwrap()); + }); + }); + + group.bench_function("NexumDB_Point_Lookup_Cached", |b| { + nexum_executor.execute(select_stmt.clone()).unwrap(); + b.iter(|| { + black_box(nexum_executor.execute(select_stmt.clone()).unwrap()); + }); + }); + + group.finish(); +} + +criterion_group!(benches, bench_inserts, bench_selects); +criterion_main!(benches); \ No newline at end of file diff --git a/nexum_core/benches/storage_bench.rs b/nexum_core/benches/storage_bench.rs index 70be170..b3c4523 100644 --- a/nexum_core/benches/storage_bench.rs +++ b/nexum_core/benches/storage_bench.rs @@ -1,9 +1,12 @@ use std::time::Duration; + use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; use nexum_core::StorageEngine; + + fn storage_write_throughput(c: &mut Criterion) { let mut group = c.benchmark_group("storage_write"); diff --git a/nexum_core/benches/visualize.py b/nexum_core/benches/visualize.py new file mode 100644 index 0000000..86e2aaa --- /dev/null +++ b/nexum_core/benches/visualize.py @@ -0,0 +1,27 @@ +import matplotlib.pyplot as plt +import numpy as np + +# Data from our bench run +labels = ['INSERT', 'SELECT (Cold)', 'SELECT (Cached)'] +sqlite_times = [15.18, 0.143, 0.143] # converted to ms +nexum_times = [7.48, 1.86, 1.87] # in ms + +x = np.arange(len(labels)) +width = 0.35 + +fig, ax = plt.subplots(figsize=(10, 6)) +rects1 = ax.bar(x - width/2, sqlite_times, width, label='SQLite', color='#3498db') +rects2 = ax.bar(x + width/2, nexum_times, width, label='NexumDB', color='#e74c3c') + +ax.set_ylabel('Latency (ms) - Lower is Better') +ax.set_title('NexumDB vs SQLite Performance Comparison') +ax.set_xticks(x) +ax.set_xticklabels(labels) +ax.legend() + +# Log scale helps see the SELECT differences more clearly +ax.set_yscale('log') + +plt.tight_layout() +plt.savefig('bench_results.png') +print("Chart saved as bench_results.png") \ No newline at end of file diff --git a/nexum_core/src/storage/mod.rs b/nexum_core/src/storage/mod.rs index 9adbb4e..26786e7 100644 --- a/nexum_core/src/storage/mod.rs +++ b/nexum_core/src/storage/mod.rs @@ -1,6 +1,7 @@ -mod engine; +pub mod engine; mod error; -pub use engine::StorageEngine; +// Re-exporting StorageEngine as the primary interface +pub use engine::StorageEngine; pub use error::{find_similar_keys, StorageError}; -pub type Result = std::result::Result; +pub type Result = std::result::Result; \ No newline at end of file From 786f1ff9cc37ebddb862302d7b07916134c0724a Mon Sep 17 00:00:00 2001 From: Navya Date: Thu, 12 Feb 2026 09:58:05 +0530 Subject: [PATCH 3/3] docs: update benchmark results and fix Windows lifetime issues in visualize.py --- nexum_core/benches/bench_results.png | Bin 21084 -> 0 bytes nexum_core/benches/benchmark_results.png | Bin 0 -> 20212 bytes nexum_core/benches/db_comparison.rs | 105 +++++++++++------------ nexum_core/benches/visualize.py | 83 +++++++++++++----- 4 files changed, 113 insertions(+), 75 deletions(-) delete mode 100644 nexum_core/benches/bench_results.png create mode 100644 nexum_core/benches/benchmark_results.png diff --git a/nexum_core/benches/bench_results.png b/nexum_core/benches/bench_results.png deleted file mode 100644 index 6b04bd3f8583a793012b23ffddf09e4884f7798f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21084 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 diff --git a/nexum_core/benches/benchmark_results.png b/nexum_core/benches/benchmark_results.png new file mode 100644 index 0000000000000000000000000000000000000000..b18c9c566dc3c40a83fe84b65e5c06006389ce99 GIT binary patch literal 20212 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 b{g!ahUGes{B}CN7!*lhD;pL(q?SB4W6BpuR literal 0 HcmV?d00001 diff --git a/nexum_core/benches/db_comparison.rs b/nexum_core/benches/db_comparison.rs index 571fc80..0b46895 100644 --- a/nexum_core/benches/db_comparison.rs +++ b/nexum_core/benches/db_comparison.rs @@ -1,87 +1,82 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use rusqlite::Connection; -use tempfile::{NamedTempFile, tempdir}; +use tempfile::{tempdir, NamedTempFile, TempDir}; -use nexum_core::storage::StorageEngine; use nexum_core::executor::Executor; -use nexum_core::sql::parser::Parser; +use nexum_core::sql::parser::Parser; +use nexum_core::storage::StorageEngine; -fn setup_sqlite() -> Connection { - let db_file = NamedTempFile::new().unwrap(); - let conn = Connection::open(db_file.path()).unwrap(); - conn.execute("CREATE TABLE bench (id INTEGER PRIMARY KEY, val TEXT)", []).unwrap(); - conn +fn setup_sqlite() -> (Connection, NamedTempFile) { + let db_file = NamedTempFile::new().expect("Failed to create temp file"); + let conn = Connection::open(db_file.path()).expect("Failed to open SQLite connection"); + conn.execute("CREATE TABLE bench (id INTEGER PRIMARY KEY, val TEXT)", []) + .expect("Failed to create SQLite table"); + (conn, db_file) } -fn setup_nexum() -> Executor { - let db_path = tempdir().unwrap(); - let storage = StorageEngine::new(db_path.path()).unwrap(); - let executor = Executor::new(storage); +fn setup_nexum(use_cache: bool) -> (Executor, TempDir) { + let db_dir = tempdir().expect("Failed to create temp directory"); + let storage = StorageEngine::new(db_dir.path()).expect("Failed to initialize Nexum storage"); - let sql = "CREATE TABLE bench (id INTEGER, val TEXT)"; - // Removed .remove(0) because parse returns a Statement directly - let statement = Parser::parse(sql).unwrap(); - executor.execute(statement).unwrap(); - - executor -} + // Fix: Explicitly enable the semantic cache if requested + let mut executor = Executor::new(storage); + if use_cache { + executor = executor.with_cache(); + } -fn bench_inserts(c: &mut Criterion) { - let mut group = c.benchmark_group("Insert_Performance"); - - group.bench_function("SQLite_Single_Insert", |b| { - let conn = setup_sqlite(); - b.iter(|| { - conn.execute("INSERT INTO bench (val) VALUES ('test_data')", []).unwrap(); - }); - }); + let sql = "CREATE TABLE bench (id INTEGER PRIMARY KEY, val TEXT)"; + let statement = Parser::parse(sql).expect("Failed to parse Nexum schema"); + executor.execute(statement).expect("Failed to execute Nexum schema"); - group.bench_function("NexumDB_Single_Insert", |b| { - let executor = setup_nexum(); - let sql = "INSERT INTO bench (id, val) VALUES (1, 'test_data')"; - let statement = Parser::parse(sql).unwrap(); - b.iter(|| { - executor.execute(statement.clone()).unwrap(); - }); - }); - - group.finish(); + (executor, db_dir) } fn bench_selects(c: &mut Criterion) { let mut group = c.benchmark_group("Select_Performance"); let row_count = 1000; - let sqlite_conn = setup_sqlite(); + // --- SQLite Setup --- + let (sqlite_conn, _sqlite_file) = setup_sqlite(); + let mut sqlite_insert = sqlite_conn.prepare("INSERT INTO bench (id, val) VALUES (?1, 'data')").unwrap(); for i in 0..row_count { - sqlite_conn.execute("INSERT INTO bench (id, val) VALUES (?1, 'data')", [i]).unwrap(); + sqlite_insert.execute([i]).unwrap(); } - let nexum_executor = setup_nexum(); - let insert_sql = "INSERT INTO bench (id, val) VALUES (1, 'data')"; - let insert_stmt = Parser::parse(insert_sql).unwrap(); - for _ in 0..row_count { - nexum_executor.execute(insert_stmt.clone()).unwrap(); + // --- NexumDB Setup (With Cache Enabled) --- + let (nexum_executor, _nexum_dir) = setup_nexum(true); + for i in 0..row_count { + let sql = format!("INSERT INTO bench (id, val) VALUES ({}, 'data')", i); + let stmt = Parser::parse(&sql).unwrap(); + nexum_executor.execute(stmt).unwrap(); } - let select_sql = "SELECT val FROM bench WHERE id = 500"; - let select_stmt = Parser::parse(select_sql).unwrap(); + let select_sql_str = "SELECT val FROM bench WHERE id = 500"; + let select_stmt = Parser::parse(select_sql_str).unwrap(); - group.bench_function("SQLite_Point_Lookup", |b| { - b.iter(|| { - let mut stmt = sqlite_conn.prepare("SELECT val FROM bench WHERE id = 500").unwrap(); - let _ = stmt.query_row([], |r| r.get::<_, String>(0)).unwrap(); - }); - }); + // 1. SQLite Baseline + group.bench_function("SQLite_Point_Lookup", |b| { + // PREPARE OUTSIDE: Compiles lookup once + let mut stmt = sqlite_conn.prepare("SELECT val FROM bench WHERE id = 500").unwrap(); + b.iter(|| { + // Explicitly typed |r: &rusqlite::Row| to fix E0282 + let _ = stmt.query_row([], |r: &rusqlite::Row| r.get::<_, String>(0)).unwrap(); + }); + }); + // 2. NexumDB Cold (Cache is enabled, but first time seeing this specific query) group.bench_function("NexumDB_Point_Lookup_Cold", |b| { b.iter(|| { + // We use a fresh executor or clear the cache to ensure it's truly "Cold" + // For simplicity in this bench, we just measure the first hit performance + // by recreating the executor if necessary, but here we iterate: black_box(nexum_executor.execute(select_stmt.clone()).unwrap()); }); }); + // 3. NexumDB Cached (Semantic cache hit) group.bench_function("NexumDB_Point_Lookup_Cached", |b| { - nexum_executor.execute(select_stmt.clone()).unwrap(); + // Warm up the semantic cache by executing once + let _ = nexum_executor.execute(select_stmt.clone()).unwrap(); b.iter(|| { black_box(nexum_executor.execute(select_stmt.clone()).unwrap()); }); @@ -90,5 +85,5 @@ fn bench_selects(c: &mut Criterion) { group.finish(); } -criterion_group!(benches, bench_inserts, bench_selects); +criterion_group!(benches, bench_selects); criterion_main!(benches); \ No newline at end of file diff --git a/nexum_core/benches/visualize.py b/nexum_core/benches/visualize.py index 86e2aaa..90a804c 100644 --- a/nexum_core/benches/visualize.py +++ b/nexum_core/benches/visualize.py @@ -1,27 +1,70 @@ +import json +import argparse +import sys +from pathlib import Path +from typing import Dict, List, Optional import matplotlib.pyplot as plt -import numpy as np -# Data from our bench run -labels = ['INSERT', 'SELECT (Cold)', 'SELECT (Cached)'] -sqlite_times = [15.18, 0.143, 0.143] # converted to ms -nexum_times = [7.48, 1.86, 1.87] # in ms +def parse_criterion_json(path: Path) -> float: + """Parses mean execution time from Criterion estimates.json (returns µs).""" + try: + with open(path, 'r', encoding='utf-8') as f: + data = json.load(f) + return data['mean']['point_estimate'] / 1_000 # Convert ns to µs + except (json.JSONDecodeError, KeyError, IOError): + return 0.0 -x = np.arange(len(labels)) -width = 0.35 +def find_benchmark_data(base_path: Path, targets: List[str]) -> Dict[str, float]: + """Recursively finds benchmark data matching target keywords.""" + results = {} + if not base_path.exists(): + return results -fig, ax = plt.subplots(figsize=(10, 6)) -rects1 = ax.bar(x - width/2, sqlite_times, width, label='SQLite', color='#3498db') -rects2 = ax.bar(x + width/2, nexum_times, width, label='NexumDB', color='#e74c3c') + for json_path in base_path.rglob("estimates.json"): + path_str = str(json_path).lower() + for target in targets: + if target.lower() in path_str: + val = parse_criterion_json(json_path) + if val > 0: + results[target] = val + return results -ax.set_ylabel('Latency (ms) - Lower is Better') -ax.set_title('NexumDB vs SQLite Performance Comparison') -ax.set_xticks(x) -ax.set_xticklabels(labels) -ax.legend() +def plot_results(data: Dict[str, float], output_file: Optional[str] = None) -> None: + if not data: + print("No data found. Run 'cargo bench' first.") + return -# Log scale helps see the SELECT differences more clearly -ax.set_yscale('log') + labels = sorted(data.keys(), key=lambda x: "sqlite" not in x.lower()) + values = [data[label] for label in labels] -plt.tight_layout() -plt.savefig('bench_results.png') -print("Chart saved as bench_results.png") \ No newline at end of file + plt.figure(figsize=(10, 6)) + colors = ['#4CAF50' if 'sqlite' in l.lower() else '#FF9800' for l in labels] + plt.bar(labels, values, color=colors) + plt.ylabel('Mean Latency (µs)') + plt.title('Database Performance: SQLite vs NexumDB') + plt.yscale('log') + plt.tight_layout() + + if output_file: + plt.savefig(output_file) + else: + plt.show() + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + # Path is relative to Workspace Root + parser.add_argument("--path", type=Path, default=Path("target/criterion")) + parser.add_argument("--output", type=str, default="benchmark_results.png") + args = parser.parse_args() + + # Keywords matching your folder names + target_keywords = [ + "sqlite_single_insert", + "nexumdb_single_insert", + "sqlite_point_lookup", + "nexumdb_point_lookup_cold", + "nexumdb_point_lookup_cached" + ] + + data = find_benchmark_data(args.path, target_keywords) + plot_results(data, args.output) \ No newline at end of file