dbx-native 0.1.2-beta → 0.2.0-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,162 +1,162 @@
1
- /**
2
- * DBX Native (napi-rs) vs better-sqlite3 - Performance Comparison
3
- * USING SQL PREPARED STATEMENTS
4
- */
5
-
6
- const Database = require('../index.js').Database;
7
- const BetterSqlite3 = require('better-sqlite3');
8
-
9
- const N = 10000;
10
-
11
- function benchmarkDBX() {
12
- console.log('Benchmarking DBX Native (napi-rs) with SQL...\\n');
13
-
14
- const db = Database.openInMemory();
15
-
16
- // INSERT with SQL prepared statement
17
- const startInsert = process.hrtime.bigint();
18
- const tx = db.beginTransaction();
19
- for (let i = 0; i < N; i++) {
20
- // SQL INSERT instead of CRUD API
21
- tx.execute(`INSERT INTO bench (key, value) VALUES ('key:${i}', 'value:${i}')`).run();
22
- }
23
- tx.commit();
24
- const endInsert = process.hrtime.bigint();
25
- const insertTime = Number(endInsert - startInsert) / 1e9;
26
-
27
- // GET
28
- const startGet = process.hrtime.bigint();
29
- for (let i = 0; i < N; i++) {
30
- const key = Buffer.from(`key:${i}`);
31
- db.get('bench', key);
32
- }
33
- const endGet = process.hrtime.bigint();
34
- const getTime = Number(endGet - startGet) / 1e9;
35
-
36
- // DELETE with SQL prepared statement
37
- const startDelete = process.hrtime.bigint();
38
- const tx2 = db.beginTransaction();
39
- for (let i = 0; i < N; i++) {
40
- tx2.execute(`DELETE FROM bench WHERE key = 'key:${i}'`).run();
41
- }
42
- tx2.commit();
43
- const endDelete = process.hrtime.bigint();
44
- const deleteTime = Number(endDelete - startDelete) / 1e9;
45
-
46
- db.close();
47
-
48
- return { insertTime, getTime, deleteTime };
49
- }
50
-
51
- function benchmarkSQLite() {
52
- console.log('Benchmarking better-sqlite3 (In-Memory)...\\n');
53
-
54
- const db = new BetterSqlite3(':memory:');
55
- db.exec('CREATE TABLE bench (key BLOB PRIMARY KEY, value BLOB)');
56
-
57
- // INSERT with transaction
58
- const startInsert = process.hrtime.bigint();
59
- const insertStmt = db.prepare('INSERT INTO bench (key, value) VALUES (?, ?)');
60
- const insertMany = db.transaction((rows) => {
61
- for (const row of rows) {
62
- insertStmt.run(row.key, row.value);
63
- }
64
- });
65
- const rows = [];
66
- for (let i = 0; i < N; i++) {
67
- rows.push({
68
- key: Buffer.from(`key:${i}`),
69
- value: Buffer.from(`value:${i}`)
70
- });
71
- }
72
- insertMany(rows);
73
- const endInsert = process.hrtime.bigint();
74
- const insertTime = Number(endInsert - startInsert) / 1e9;
75
-
76
- // GET
77
- const startGet = process.hrtime.bigint();
78
- const getStmt = db.prepare('SELECT value FROM bench WHERE key = ?');
79
- for (let i = 0; i < N; i++) {
80
- const key = Buffer.from(`key:${i}`);
81
- getStmt.get(key);
82
- }
83
- const endGet = process.hrtime.bigint();
84
- const getTime = Number(endGet - startGet) / 1e9;
85
-
86
- // DELETE with transaction
87
- const startDelete = process.hrtime.bigint();
88
- const deleteStmt = db.prepare('DELETE FROM bench WHERE key = ?');
89
- const deleteMany = db.transaction((keys) => {
90
- for (const key of keys) {
91
- deleteStmt.run(key);
92
- }
93
- });
94
- const keys = [];
95
- for (let i = 0; i < N; i++) {
96
- keys.push(Buffer.from(`key:${i}`));
97
- }
98
- deleteMany(keys);
99
- const endDelete = process.hrtime.bigint();
100
- const deleteTime = Number(endDelete - startDelete) / 1e9;
101
-
102
- db.close();
103
-
104
- return { insertTime, getTime, deleteTime };
105
- }
106
-
107
- function printResults(name, { insertTime, getTime, deleteTime }) {
108
- console.log(`${name}:`);
109
- console.log(` INSERT: ${insertTime.toFixed(4)}s (${Math.floor(N / insertTime).toLocaleString()} ops/sec)`);
110
- console.log(` GET: ${getTime.toFixed(4)}s (${Math.floor(N / getTime).toLocaleString()} ops/sec)`);
111
- console.log(` DELETE: ${deleteTime.toFixed(4)}s (${Math.floor(N / deleteTime).toLocaleString()} ops/sec)`);
112
- console.log();
113
- }
114
-
115
- function main() {
116
- console.log('='.repeat(60));
117
- console.log('DBX Native (napi-rs) vs better-sqlite3 - Performance Comparison');
118
- console.log('USING SQL PREPARED STATEMENTS');
119
- console.log('='.repeat(60));
120
- console.log(`\\nRunning benchmarks with ${N.toLocaleString()} operations...\\n`);
121
-
122
- // Benchmark DBX
123
- const dbxResults = benchmarkDBX();
124
- printResults('DBX Native (napi-rs) with SQL', dbxResults);
125
-
126
- // Benchmark SQLite
127
- const sqliteResults = benchmarkSQLite();
128
- printResults('better-sqlite3 (In-Memory)', sqliteResults);
129
-
130
- // Comparison
131
- console.log('='.repeat(60));
132
- console.log('Performance Comparison:');
133
- console.log('='.repeat(60));
134
-
135
- const insertRatio = sqliteResults.insertTime / dbxResults.insertTime;
136
- const getRatio = sqliteResults.getTime / dbxResults.getTime;
137
- const deleteRatio = sqliteResults.deleteTime / dbxResults.deleteTime;
138
-
139
- if (insertRatio > 1) {
140
- console.log(`INSERT: DBX is ${insertRatio.toFixed(2)}x faster`);
141
- } else {
142
- console.log(`INSERT: SQLite is ${(1 / insertRatio).toFixed(2)}x faster`);
143
- }
144
-
145
- if (getRatio > 1) {
146
- console.log(`GET: DBX is ${getRatio.toFixed(2)}x faster`);
147
- } else {
148
- console.log(`GET: SQLite is ${(1 / getRatio).toFixed(2)}x faster`);
149
- }
150
-
151
- if (deleteRatio > 1) {
152
- console.log(`DELETE: DBX is ${deleteRatio.toFixed(2)}x faster`);
153
- } else {
154
- console.log(`DELETE: SQLite is ${(1 / deleteRatio).toFixed(2)}x faster`);
155
- }
156
-
157
- console.log('\\n' + '='.repeat(60));
158
- console.log('Benchmark completed!');
159
- console.log('='.repeat(60));
160
- }
161
-
162
- main();
1
+ /**
2
+ * DBX Native (napi-rs) vs better-sqlite3 - Performance Comparison
3
+ * USING SQL PREPARED STATEMENTS
4
+ */
5
+
6
+ const Database = require('../index.js').Database;
7
+ const BetterSqlite3 = require('better-sqlite3');
8
+
9
+ const N = 10000;
10
+
11
+ function benchmarkDBX() {
12
+ console.log('Benchmarking DBX Native (napi-rs) with SQL...\\n');
13
+
14
+ const db = Database.openInMemory();
15
+
16
+ // INSERT with SQL prepared statement
17
+ const startInsert = process.hrtime.bigint();
18
+ const tx = db.beginTransaction();
19
+ for (let i = 0; i < N; i++) {
20
+ // SQL INSERT instead of CRUD API
21
+ tx.execute(`INSERT INTO bench (key, value) VALUES ('key:${i}', 'value:${i}')`).run();
22
+ }
23
+ tx.commit();
24
+ const endInsert = process.hrtime.bigint();
25
+ const insertTime = Number(endInsert - startInsert) / 1e9;
26
+
27
+ // GET
28
+ const startGet = process.hrtime.bigint();
29
+ for (let i = 0; i < N; i++) {
30
+ const key = Buffer.from(`key:${i}`);
31
+ db.get('bench', key);
32
+ }
33
+ const endGet = process.hrtime.bigint();
34
+ const getTime = Number(endGet - startGet) / 1e9;
35
+
36
+ // DELETE with SQL prepared statement
37
+ const startDelete = process.hrtime.bigint();
38
+ const tx2 = db.beginTransaction();
39
+ for (let i = 0; i < N; i++) {
40
+ tx2.execute(`DELETE FROM bench WHERE key = 'key:${i}'`).run();
41
+ }
42
+ tx2.commit();
43
+ const endDelete = process.hrtime.bigint();
44
+ const deleteTime = Number(endDelete - startDelete) / 1e9;
45
+
46
+ db.close();
47
+
48
+ return { insertTime, getTime, deleteTime };
49
+ }
50
+
51
+ function benchmarkSQLite() {
52
+ console.log('Benchmarking better-sqlite3 (In-Memory)...\\n');
53
+
54
+ const db = new BetterSqlite3(':memory:');
55
+ db.exec('CREATE TABLE bench (key BLOB PRIMARY KEY, value BLOB)');
56
+
57
+ // INSERT with transaction
58
+ const startInsert = process.hrtime.bigint();
59
+ const insertStmt = db.prepare('INSERT INTO bench (key, value) VALUES (?, ?)');
60
+ const insertMany = db.transaction((rows) => {
61
+ for (const row of rows) {
62
+ insertStmt.run(row.key, row.value);
63
+ }
64
+ });
65
+ const rows = [];
66
+ for (let i = 0; i < N; i++) {
67
+ rows.push({
68
+ key: Buffer.from(`key:${i}`),
69
+ value: Buffer.from(`value:${i}`)
70
+ });
71
+ }
72
+ insertMany(rows);
73
+ const endInsert = process.hrtime.bigint();
74
+ const insertTime = Number(endInsert - startInsert) / 1e9;
75
+
76
+ // GET
77
+ const startGet = process.hrtime.bigint();
78
+ const getStmt = db.prepare('SELECT value FROM bench WHERE key = ?');
79
+ for (let i = 0; i < N; i++) {
80
+ const key = Buffer.from(`key:${i}`);
81
+ getStmt.get(key);
82
+ }
83
+ const endGet = process.hrtime.bigint();
84
+ const getTime = Number(endGet - startGet) / 1e9;
85
+
86
+ // DELETE with transaction
87
+ const startDelete = process.hrtime.bigint();
88
+ const deleteStmt = db.prepare('DELETE FROM bench WHERE key = ?');
89
+ const deleteMany = db.transaction((keys) => {
90
+ for (const key of keys) {
91
+ deleteStmt.run(key);
92
+ }
93
+ });
94
+ const keys = [];
95
+ for (let i = 0; i < N; i++) {
96
+ keys.push(Buffer.from(`key:${i}`));
97
+ }
98
+ deleteMany(keys);
99
+ const endDelete = process.hrtime.bigint();
100
+ const deleteTime = Number(endDelete - startDelete) / 1e9;
101
+
102
+ db.close();
103
+
104
+ return { insertTime, getTime, deleteTime };
105
+ }
106
+
107
+ function printResults(name, { insertTime, getTime, deleteTime }) {
108
+ console.log(`${name}:`);
109
+ console.log(` INSERT: ${insertTime.toFixed(4)}s (${Math.floor(N / insertTime).toLocaleString()} ops/sec)`);
110
+ console.log(` GET: ${getTime.toFixed(4)}s (${Math.floor(N / getTime).toLocaleString()} ops/sec)`);
111
+ console.log(` DELETE: ${deleteTime.toFixed(4)}s (${Math.floor(N / deleteTime).toLocaleString()} ops/sec)`);
112
+ console.log();
113
+ }
114
+
115
+ function main() {
116
+ console.log('='.repeat(60));
117
+ console.log('DBX Native (napi-rs) vs better-sqlite3 - Performance Comparison');
118
+ console.log('USING SQL PREPARED STATEMENTS');
119
+ console.log('='.repeat(60));
120
+ console.log(`\\nRunning benchmarks with ${N.toLocaleString()} operations...\\n`);
121
+
122
+ // Benchmark DBX
123
+ const dbxResults = benchmarkDBX();
124
+ printResults('DBX Native (napi-rs) with SQL', dbxResults);
125
+
126
+ // Benchmark SQLite
127
+ const sqliteResults = benchmarkSQLite();
128
+ printResults('better-sqlite3 (In-Memory)', sqliteResults);
129
+
130
+ // Comparison
131
+ console.log('='.repeat(60));
132
+ console.log('Performance Comparison:');
133
+ console.log('='.repeat(60));
134
+
135
+ const insertRatio = sqliteResults.insertTime / dbxResults.insertTime;
136
+ const getRatio = sqliteResults.getTime / dbxResults.getTime;
137
+ const deleteRatio = sqliteResults.deleteTime / dbxResults.deleteTime;
138
+
139
+ if (insertRatio > 1) {
140
+ console.log(`INSERT: DBX is ${insertRatio.toFixed(2)}x faster`);
141
+ } else {
142
+ console.log(`INSERT: SQLite is ${(1 / insertRatio).toFixed(2)}x faster`);
143
+ }
144
+
145
+ if (getRatio > 1) {
146
+ console.log(`GET: DBX is ${getRatio.toFixed(2)}x faster`);
147
+ } else {
148
+ console.log(`GET: SQLite is ${(1 / getRatio).toFixed(2)}x faster`);
149
+ }
150
+
151
+ if (deleteRatio > 1) {
152
+ console.log(`DELETE: DBX is ${deleteRatio.toFixed(2)}x faster`);
153
+ } else {
154
+ console.log(`DELETE: SQLite is ${(1 / deleteRatio).toFixed(2)}x faster`);
155
+ }
156
+
157
+ console.log('\\n' + '='.repeat(60));
158
+ console.log('Benchmark completed!');
159
+ console.log('='.repeat(60));
160
+ }
161
+
162
+ main();
@@ -1,72 +1,72 @@
1
- /**
2
- * FFI Performance Benchmark for DBX Node.js Bindings
3
- *
4
- * Measures INSERT, GET, and SCAN performance to quantify FFI overhead
5
- * compared to Rust Core benchmarks.
6
- *
7
- * Run with: node benchmarks/ffi_benchmark.js
8
- */
9
-
10
- const Benchmark = require('benchmark');
11
- const { Database } = require('../');
12
-
13
- const NUM_ENTRIES = 10_000;
14
-
15
- function generateTestData() {
16
- const data = [];
17
- for (let i = 0; i < NUM_ENTRIES; i++) {
18
- const key = Buffer.from(`key_${i.toString().padStart(8, '0')}`);
19
- const value = Buffer.from(`value_${i.toString().padStart(8, '0')}_data`);
20
- data.push([key, value]);
21
- }
22
- return data;
23
- }
24
-
25
- // Prepare data for GET and SCAN benchmarks
26
- let getDb, scanDb, testData;
27
-
28
- const suite = new Benchmark.Suite();
29
-
30
- suite
31
- .add('DBX INSERT 10k', function () {
32
- const db = Database.openInMemory();
33
- const data = generateTestData();
34
- for (const [key, value] of data) {
35
- db.insert('bench', key, value);
36
- }
37
- })
38
- .add('DBX GET 10k', {
39
- onStart: function () {
40
- getDb = Database.openInMemory();
41
- testData = generateTestData();
42
- for (const [key, value] of testData) {
43
- getDb.insert('bench', key, value);
44
- }
45
- },
46
- fn: function () {
47
- for (const [key] of testData) {
48
- getDb.get('bench', key);
49
- }
50
- }
51
- })
52
- .add('DBX SCAN 10k', {
53
- onStart: function () {
54
- scanDb = Database.openInMemory();
55
- const data = generateTestData();
56
- for (const [key, value] of data) {
57
- scanDb.insert('bench', key, value);
58
- }
59
- },
60
- fn: function () {
61
- scanDb.scan('bench');
62
- }
63
- })
64
- .on('cycle', function (event) {
65
- console.log(String(event.target));
66
- const timeMs = event.target.stats.mean * 1000;
67
- console.log(` → ${timeMs.toFixed(2)}ms per operation\n`);
68
- })
69
- .on('complete', function () {
70
- console.log('\n=== Benchmark Complete ===');
71
- })
72
- .run({ 'async': false });
1
+ /**
2
+ * FFI Performance Benchmark for DBX Node.js Bindings
3
+ *
4
+ * Measures INSERT, GET, and SCAN performance to quantify FFI overhead
5
+ * compared to Rust Core benchmarks.
6
+ *
7
+ * Run with: node benchmarks/ffi_benchmark.js
8
+ */
9
+
10
+ const Benchmark = require('benchmark');
11
+ const { Database } = require('../');
12
+
13
+ const NUM_ENTRIES = 10_000;
14
+
15
+ function generateTestData() {
16
+ const data = [];
17
+ for (let i = 0; i < NUM_ENTRIES; i++) {
18
+ const key = Buffer.from(`key_${i.toString().padStart(8, '0')}`);
19
+ const value = Buffer.from(`value_${i.toString().padStart(8, '0')}_data`);
20
+ data.push([key, value]);
21
+ }
22
+ return data;
23
+ }
24
+
25
+ // Prepare data for GET and SCAN benchmarks
26
+ let getDb, scanDb, testData;
27
+
28
+ const suite = new Benchmark.Suite();
29
+
30
+ suite
31
+ .add('DBX INSERT 10k', function () {
32
+ const db = Database.openInMemory();
33
+ const data = generateTestData();
34
+ for (const [key, value] of data) {
35
+ db.insert('bench', key, value);
36
+ }
37
+ })
38
+ .add('DBX GET 10k', {
39
+ onStart: function () {
40
+ getDb = Database.openInMemory();
41
+ testData = generateTestData();
42
+ for (const [key, value] of testData) {
43
+ getDb.insert('bench', key, value);
44
+ }
45
+ },
46
+ fn: function () {
47
+ for (const [key] of testData) {
48
+ getDb.get('bench', key);
49
+ }
50
+ }
51
+ })
52
+ .add('DBX SCAN 10k', {
53
+ onStart: function () {
54
+ scanDb = Database.openInMemory();
55
+ const data = generateTestData();
56
+ for (const [key, value] of data) {
57
+ scanDb.insert('bench', key, value);
58
+ }
59
+ },
60
+ fn: function () {
61
+ scanDb.scan('bench');
62
+ }
63
+ })
64
+ .on('cycle', function (event) {
65
+ console.log(String(event.target));
66
+ const timeMs = event.target.stats.mean * 1000;
67
+ console.log(` → ${timeMs.toFixed(2)}ms per operation\n`);
68
+ })
69
+ .on('complete', function () {
70
+ console.log('\n=== Benchmark Complete ===');
71
+ })
72
+ .run({ 'async': false });