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.
- package/README.md +88 -88
- package/artifacts/node-binary-macos-latest/index.node +0 -0
- package/artifacts/node-binary-ubuntu-latest/index.node +0 -0
- package/artifacts/node-binary-windows-latest/index.node +0 -0
- package/benchmarks/auto_batch_benchmark.js +98 -98
- package/benchmarks/benchmark.js +162 -162
- package/benchmarks/benchmark_batch.js +166 -166
- package/benchmarks/benchmark_sql.js +162 -162
- package/benchmarks/ffi_benchmark.js +72 -72
- package/benchmarks/zero_copy_benchmark.js +109 -109
- package/dbx-native-0.2.0-beta.tgz +0 -0
- package/examples/basic.js +34 -34
- package/index.js +2 -2
- package/package.json +46 -46
- package/smart_database.js +184 -184
- package/test/test_sql_insert.js +72 -72
- package/dbx-native-0.1.2-beta.tgz +0 -0
package/benchmarks/benchmark.js
CHANGED
|
@@ -1,162 +1,162 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DBX Native (napi-rs) vs better-sqlite3 - Performance Comparison
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const Database = require('../index.js').Database;
|
|
6
|
-
const BetterSqlite3 = require('better-sqlite3');
|
|
7
|
-
|
|
8
|
-
const N = 10000;
|
|
9
|
-
|
|
10
|
-
function benchmarkDBX() {
|
|
11
|
-
console.log('Benchmarking DBX Native (napi-rs)...\n');
|
|
12
|
-
|
|
13
|
-
const db = Database.openInMemory();
|
|
14
|
-
|
|
15
|
-
// INSERT with transaction
|
|
16
|
-
const startInsert = process.hrtime.bigint();
|
|
17
|
-
const tx = db.beginTransaction();
|
|
18
|
-
for (let i = 0; i < N; i++) {
|
|
19
|
-
const key = Buffer.from(`key:${i}`);
|
|
20
|
-
const value = Buffer.from(`value:${i}`);
|
|
21
|
-
tx.insert('bench', key, value);
|
|
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 transaction
|
|
37
|
-
const startDelete = process.hrtime.bigint();
|
|
38
|
-
const tx2 = db.beginTransaction();
|
|
39
|
-
for (let i = 0; i < N; i++) {
|
|
40
|
-
const key = Buffer.from(`key:${i}`);
|
|
41
|
-
tx2.delete('bench', key);
|
|
42
|
-
}
|
|
43
|
-
tx2.commit();
|
|
44
|
-
const endDelete = process.hrtime.bigint();
|
|
45
|
-
const deleteTime = Number(endDelete - startDelete) / 1e9;
|
|
46
|
-
|
|
47
|
-
db.close();
|
|
48
|
-
|
|
49
|
-
return { insertTime, getTime, deleteTime };
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function benchmarkSQLite() {
|
|
53
|
-
console.log('Benchmarking better-sqlite3 (In-Memory)...\n');
|
|
54
|
-
|
|
55
|
-
const db = new BetterSqlite3(':memory:');
|
|
56
|
-
db.exec('CREATE TABLE bench (key BLOB PRIMARY KEY, value BLOB)');
|
|
57
|
-
|
|
58
|
-
// INSERT with transaction
|
|
59
|
-
const startInsert = process.hrtime.bigint();
|
|
60
|
-
const insertStmt = db.prepare('INSERT INTO bench (key, value) VALUES (?, ?)');
|
|
61
|
-
const insertMany = db.transaction((rows) => {
|
|
62
|
-
for (const row of rows) {
|
|
63
|
-
insertStmt.run(row.key, row.value);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
const rows = [];
|
|
67
|
-
for (let i = 0; i < N; i++) {
|
|
68
|
-
rows.push({
|
|
69
|
-
key: Buffer.from(`key:${i}`),
|
|
70
|
-
value: Buffer.from(`value:${i}`)
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
insertMany(rows);
|
|
74
|
-
const endInsert = process.hrtime.bigint();
|
|
75
|
-
const insertTime = Number(endInsert - startInsert) / 1e9;
|
|
76
|
-
|
|
77
|
-
// GET
|
|
78
|
-
const startGet = process.hrtime.bigint();
|
|
79
|
-
const getStmt = db.prepare('SELECT value FROM bench WHERE key = ?');
|
|
80
|
-
for (let i = 0; i < N; i++) {
|
|
81
|
-
const key = Buffer.from(`key:${i}`);
|
|
82
|
-
getStmt.get(key);
|
|
83
|
-
}
|
|
84
|
-
const endGet = process.hrtime.bigint();
|
|
85
|
-
const getTime = Number(endGet - startGet) / 1e9;
|
|
86
|
-
|
|
87
|
-
// DELETE with transaction
|
|
88
|
-
const startDelete = process.hrtime.bigint();
|
|
89
|
-
const deleteStmt = db.prepare('DELETE FROM bench WHERE key = ?');
|
|
90
|
-
const deleteMany = db.transaction((keys) => {
|
|
91
|
-
for (const key of keys) {
|
|
92
|
-
deleteStmt.run(key);
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
const keys = [];
|
|
96
|
-
for (let i = 0; i < N; i++) {
|
|
97
|
-
keys.push(Buffer.from(`key:${i}`));
|
|
98
|
-
}
|
|
99
|
-
deleteMany(keys);
|
|
100
|
-
const endDelete = process.hrtime.bigint();
|
|
101
|
-
const deleteTime = Number(endDelete - startDelete) / 1e9;
|
|
102
|
-
|
|
103
|
-
db.close();
|
|
104
|
-
|
|
105
|
-
return { insertTime, getTime, deleteTime };
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function printResults(name, { insertTime, getTime, deleteTime }) {
|
|
109
|
-
console.log(`${name}:`);
|
|
110
|
-
console.log(` INSERT: ${insertTime.toFixed(4)}s (${Math.floor(N / insertTime).toLocaleString()} ops/sec)`);
|
|
111
|
-
console.log(` GET: ${getTime.toFixed(4)}s (${Math.floor(N / getTime).toLocaleString()} ops/sec)`);
|
|
112
|
-
console.log(` DELETE: ${deleteTime.toFixed(4)}s (${Math.floor(N / deleteTime).toLocaleString()} ops/sec)`);
|
|
113
|
-
console.log();
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function main() {
|
|
117
|
-
console.log('='.repeat(60));
|
|
118
|
-
console.log('DBX Native (napi-rs) vs better-sqlite3 - Performance Comparison');
|
|
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)', 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
|
+
*/
|
|
4
|
+
|
|
5
|
+
const Database = require('../index.js').Database;
|
|
6
|
+
const BetterSqlite3 = require('better-sqlite3');
|
|
7
|
+
|
|
8
|
+
const N = 10000;
|
|
9
|
+
|
|
10
|
+
function benchmarkDBX() {
|
|
11
|
+
console.log('Benchmarking DBX Native (napi-rs)...\n');
|
|
12
|
+
|
|
13
|
+
const db = Database.openInMemory();
|
|
14
|
+
|
|
15
|
+
// INSERT with transaction
|
|
16
|
+
const startInsert = process.hrtime.bigint();
|
|
17
|
+
const tx = db.beginTransaction();
|
|
18
|
+
for (let i = 0; i < N; i++) {
|
|
19
|
+
const key = Buffer.from(`key:${i}`);
|
|
20
|
+
const value = Buffer.from(`value:${i}`);
|
|
21
|
+
tx.insert('bench', key, value);
|
|
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 transaction
|
|
37
|
+
const startDelete = process.hrtime.bigint();
|
|
38
|
+
const tx2 = db.beginTransaction();
|
|
39
|
+
for (let i = 0; i < N; i++) {
|
|
40
|
+
const key = Buffer.from(`key:${i}`);
|
|
41
|
+
tx2.delete('bench', key);
|
|
42
|
+
}
|
|
43
|
+
tx2.commit();
|
|
44
|
+
const endDelete = process.hrtime.bigint();
|
|
45
|
+
const deleteTime = Number(endDelete - startDelete) / 1e9;
|
|
46
|
+
|
|
47
|
+
db.close();
|
|
48
|
+
|
|
49
|
+
return { insertTime, getTime, deleteTime };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function benchmarkSQLite() {
|
|
53
|
+
console.log('Benchmarking better-sqlite3 (In-Memory)...\n');
|
|
54
|
+
|
|
55
|
+
const db = new BetterSqlite3(':memory:');
|
|
56
|
+
db.exec('CREATE TABLE bench (key BLOB PRIMARY KEY, value BLOB)');
|
|
57
|
+
|
|
58
|
+
// INSERT with transaction
|
|
59
|
+
const startInsert = process.hrtime.bigint();
|
|
60
|
+
const insertStmt = db.prepare('INSERT INTO bench (key, value) VALUES (?, ?)');
|
|
61
|
+
const insertMany = db.transaction((rows) => {
|
|
62
|
+
for (const row of rows) {
|
|
63
|
+
insertStmt.run(row.key, row.value);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
const rows = [];
|
|
67
|
+
for (let i = 0; i < N; i++) {
|
|
68
|
+
rows.push({
|
|
69
|
+
key: Buffer.from(`key:${i}`),
|
|
70
|
+
value: Buffer.from(`value:${i}`)
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
insertMany(rows);
|
|
74
|
+
const endInsert = process.hrtime.bigint();
|
|
75
|
+
const insertTime = Number(endInsert - startInsert) / 1e9;
|
|
76
|
+
|
|
77
|
+
// GET
|
|
78
|
+
const startGet = process.hrtime.bigint();
|
|
79
|
+
const getStmt = db.prepare('SELECT value FROM bench WHERE key = ?');
|
|
80
|
+
for (let i = 0; i < N; i++) {
|
|
81
|
+
const key = Buffer.from(`key:${i}`);
|
|
82
|
+
getStmt.get(key);
|
|
83
|
+
}
|
|
84
|
+
const endGet = process.hrtime.bigint();
|
|
85
|
+
const getTime = Number(endGet - startGet) / 1e9;
|
|
86
|
+
|
|
87
|
+
// DELETE with transaction
|
|
88
|
+
const startDelete = process.hrtime.bigint();
|
|
89
|
+
const deleteStmt = db.prepare('DELETE FROM bench WHERE key = ?');
|
|
90
|
+
const deleteMany = db.transaction((keys) => {
|
|
91
|
+
for (const key of keys) {
|
|
92
|
+
deleteStmt.run(key);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
const keys = [];
|
|
96
|
+
for (let i = 0; i < N; i++) {
|
|
97
|
+
keys.push(Buffer.from(`key:${i}`));
|
|
98
|
+
}
|
|
99
|
+
deleteMany(keys);
|
|
100
|
+
const endDelete = process.hrtime.bigint();
|
|
101
|
+
const deleteTime = Number(endDelete - startDelete) / 1e9;
|
|
102
|
+
|
|
103
|
+
db.close();
|
|
104
|
+
|
|
105
|
+
return { insertTime, getTime, deleteTime };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function printResults(name, { insertTime, getTime, deleteTime }) {
|
|
109
|
+
console.log(`${name}:`);
|
|
110
|
+
console.log(` INSERT: ${insertTime.toFixed(4)}s (${Math.floor(N / insertTime).toLocaleString()} ops/sec)`);
|
|
111
|
+
console.log(` GET: ${getTime.toFixed(4)}s (${Math.floor(N / getTime).toLocaleString()} ops/sec)`);
|
|
112
|
+
console.log(` DELETE: ${deleteTime.toFixed(4)}s (${Math.floor(N / deleteTime).toLocaleString()} ops/sec)`);
|
|
113
|
+
console.log();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function main() {
|
|
117
|
+
console.log('='.repeat(60));
|
|
118
|
+
console.log('DBX Native (napi-rs) vs better-sqlite3 - Performance Comparison');
|
|
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)', 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,166 +1,166 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DBX Native (napi-rs) vs better-sqlite3 - Performance Comparison
|
|
3
|
-
* WITH BATCH API OPTIMIZATION
|
|
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 Batch API...\n');
|
|
13
|
-
|
|
14
|
-
const db = Database.openInMemory();
|
|
15
|
-
|
|
16
|
-
// INSERT with batch API
|
|
17
|
-
const rows = [];
|
|
18
|
-
for (let i = 0; i < N; i++) {
|
|
19
|
-
rows.push([
|
|
20
|
-
Buffer.from(`key:${i}`),
|
|
21
|
-
Buffer.from(`value:${i}`)
|
|
22
|
-
]);
|
|
23
|
-
}
|
|
24
|
-
const startInsert = process.hrtime.bigint();
|
|
25
|
-
db.insertBatch('bench', rows);
|
|
26
|
-
const endInsert = process.hrtime.bigint();
|
|
27
|
-
const insertTime = Number(endInsert - startInsert) / 1e9;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// GET
|
|
31
|
-
const startGet = process.hrtime.bigint();
|
|
32
|
-
for (let i = 0; i < N; i++) {
|
|
33
|
-
const key = Buffer.from(`key:${i}`);
|
|
34
|
-
db.get('bench', key);
|
|
35
|
-
}
|
|
36
|
-
const endGet = process.hrtime.bigint();
|
|
37
|
-
const getTime = Number(endGet - startGet) / 1e9;
|
|
38
|
-
|
|
39
|
-
// DELETE with batch API
|
|
40
|
-
const keys = [];
|
|
41
|
-
for (let i = 0; i < N; i++) {
|
|
42
|
-
keys.push(Buffer.from(`key:${i}`));
|
|
43
|
-
}
|
|
44
|
-
const startDelete = process.hrtime.bigint();
|
|
45
|
-
db.deleteBatch('bench', keys);
|
|
46
|
-
const endDelete = process.hrtime.bigint();
|
|
47
|
-
const deleteTime = Number(endDelete - startDelete) / 1e9;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
db.close();
|
|
51
|
-
|
|
52
|
-
return { insertTime, getTime, deleteTime };
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function benchmarkSQLite() {
|
|
56
|
-
console.log('Benchmarking better-sqlite3 (In-Memory)...\n');
|
|
57
|
-
|
|
58
|
-
const db = new BetterSqlite3(':memory:');
|
|
59
|
-
db.exec('CREATE TABLE bench (key BLOB PRIMARY KEY, value BLOB)');
|
|
60
|
-
|
|
61
|
-
// INSERT with transaction
|
|
62
|
-
const startInsert = process.hrtime.bigint();
|
|
63
|
-
const insertStmt = db.prepare('INSERT INTO bench (key, value) VALUES (?, ?)');
|
|
64
|
-
const insertMany = db.transaction((rows) => {
|
|
65
|
-
for (const row of rows) {
|
|
66
|
-
insertStmt.run(row.key, row.value);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
const rows = [];
|
|
70
|
-
for (let i = 0; i < N; i++) {
|
|
71
|
-
rows.push({
|
|
72
|
-
key: Buffer.from(`key:${i}`),
|
|
73
|
-
value: Buffer.from(`value:${i}`)
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
insertMany(rows);
|
|
77
|
-
const endInsert = process.hrtime.bigint();
|
|
78
|
-
const insertTime = Number(endInsert - startInsert) / 1e9;
|
|
79
|
-
|
|
80
|
-
// GET
|
|
81
|
-
const startGet = process.hrtime.bigint();
|
|
82
|
-
const getStmt = db.prepare('SELECT value FROM bench WHERE key = ?');
|
|
83
|
-
for (let i = 0; i < N; i++) {
|
|
84
|
-
const key = Buffer.from(`key:${i}`);
|
|
85
|
-
getStmt.get(key);
|
|
86
|
-
}
|
|
87
|
-
const endGet = process.hrtime.bigint();
|
|
88
|
-
const getTime = Number(endGet - startGet) / 1e9;
|
|
89
|
-
|
|
90
|
-
// DELETE with transaction
|
|
91
|
-
const startDelete = process.hrtime.bigint();
|
|
92
|
-
const deleteStmt = db.prepare('DELETE FROM bench WHERE key = ?');
|
|
93
|
-
const deleteMany = db.transaction((keys) => {
|
|
94
|
-
for (const key of keys) {
|
|
95
|
-
deleteStmt.run(key);
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
const keys = [];
|
|
99
|
-
for (let i = 0; i < N; i++) {
|
|
100
|
-
keys.push(Buffer.from(`key:${i}`));
|
|
101
|
-
}
|
|
102
|
-
deleteMany(keys);
|
|
103
|
-
const endDelete = process.hrtime.bigint();
|
|
104
|
-
const deleteTime = Number(endDelete - startDelete) / 1e9;
|
|
105
|
-
|
|
106
|
-
db.close();
|
|
107
|
-
|
|
108
|
-
return { insertTime, getTime, deleteTime };
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function printResults(name, { insertTime, getTime, deleteTime }) {
|
|
112
|
-
console.log(`${name}:`);
|
|
113
|
-
console.log(` INSERT: ${insertTime.toFixed(4)}s (${Math.floor(N / insertTime).toLocaleString()} ops/sec)`);
|
|
114
|
-
console.log(` GET: ${getTime.toFixed(4)}s (${Math.floor(N / getTime).toLocaleString()} ops/sec)`);
|
|
115
|
-
console.log(` DELETE: ${deleteTime.toFixed(4)}s (${Math.floor(N / deleteTime).toLocaleString()} ops/sec)`);
|
|
116
|
-
console.log();
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function main() {
|
|
120
|
-
console.log('='.repeat(60));
|
|
121
|
-
console.log('DBX Native (napi-rs) vs better-sqlite3 - Performance Comparison');
|
|
122
|
-
console.log('WITH BATCH API OPTIMIZATION');
|
|
123
|
-
console.log('='.repeat(60));
|
|
124
|
-
console.log(`\nRunning benchmarks with ${N.toLocaleString()} operations...\n`);
|
|
125
|
-
|
|
126
|
-
// Benchmark DBX
|
|
127
|
-
const dbxResults = benchmarkDBX();
|
|
128
|
-
printResults('DBX Native (napi-rs) with Batch API', dbxResults);
|
|
129
|
-
|
|
130
|
-
// Benchmark SQLite
|
|
131
|
-
const sqliteResults = benchmarkSQLite();
|
|
132
|
-
printResults('better-sqlite3 (In-Memory)', sqliteResults);
|
|
133
|
-
|
|
134
|
-
// Comparison
|
|
135
|
-
console.log('='.repeat(60));
|
|
136
|
-
console.log('Performance Comparison:');
|
|
137
|
-
console.log('='.repeat(60));
|
|
138
|
-
|
|
139
|
-
const insertRatio = sqliteResults.insertTime / dbxResults.insertTime;
|
|
140
|
-
const getRatio = sqliteResults.getTime / dbxResults.getTime;
|
|
141
|
-
const deleteRatio = sqliteResults.deleteTime / dbxResults.deleteTime;
|
|
142
|
-
|
|
143
|
-
if (insertRatio > 1) {
|
|
144
|
-
console.log(`INSERT: DBX is ${insertRatio.toFixed(2)}x faster`);
|
|
145
|
-
} else {
|
|
146
|
-
console.log(`INSERT: SQLite is ${(1 / insertRatio).toFixed(2)}x faster`);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (getRatio > 1) {
|
|
150
|
-
console.log(`GET: DBX is ${getRatio.toFixed(2)}x faster`);
|
|
151
|
-
} else {
|
|
152
|
-
console.log(`GET: SQLite is ${(1 / getRatio).toFixed(2)}x faster`);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
if (deleteRatio > 1) {
|
|
156
|
-
console.log(`DELETE: DBX is ${deleteRatio.toFixed(2)}x faster`);
|
|
157
|
-
} else {
|
|
158
|
-
console.log(`DELETE: SQLite is ${(1 / deleteRatio).toFixed(2)}x faster`);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
console.log('\n' + '='.repeat(60));
|
|
162
|
-
console.log('Benchmark completed!');
|
|
163
|
-
console.log('='.repeat(60));
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
main();
|
|
1
|
+
/**
|
|
2
|
+
* DBX Native (napi-rs) vs better-sqlite3 - Performance Comparison
|
|
3
|
+
* WITH BATCH API OPTIMIZATION
|
|
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 Batch API...\n');
|
|
13
|
+
|
|
14
|
+
const db = Database.openInMemory();
|
|
15
|
+
|
|
16
|
+
// INSERT with batch API
|
|
17
|
+
const rows = [];
|
|
18
|
+
for (let i = 0; i < N; i++) {
|
|
19
|
+
rows.push([
|
|
20
|
+
Buffer.from(`key:${i}`),
|
|
21
|
+
Buffer.from(`value:${i}`)
|
|
22
|
+
]);
|
|
23
|
+
}
|
|
24
|
+
const startInsert = process.hrtime.bigint();
|
|
25
|
+
db.insertBatch('bench', rows);
|
|
26
|
+
const endInsert = process.hrtime.bigint();
|
|
27
|
+
const insertTime = Number(endInsert - startInsert) / 1e9;
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
// GET
|
|
31
|
+
const startGet = process.hrtime.bigint();
|
|
32
|
+
for (let i = 0; i < N; i++) {
|
|
33
|
+
const key = Buffer.from(`key:${i}`);
|
|
34
|
+
db.get('bench', key);
|
|
35
|
+
}
|
|
36
|
+
const endGet = process.hrtime.bigint();
|
|
37
|
+
const getTime = Number(endGet - startGet) / 1e9;
|
|
38
|
+
|
|
39
|
+
// DELETE with batch API
|
|
40
|
+
const keys = [];
|
|
41
|
+
for (let i = 0; i < N; i++) {
|
|
42
|
+
keys.push(Buffer.from(`key:${i}`));
|
|
43
|
+
}
|
|
44
|
+
const startDelete = process.hrtime.bigint();
|
|
45
|
+
db.deleteBatch('bench', keys);
|
|
46
|
+
const endDelete = process.hrtime.bigint();
|
|
47
|
+
const deleteTime = Number(endDelete - startDelete) / 1e9;
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
db.close();
|
|
51
|
+
|
|
52
|
+
return { insertTime, getTime, deleteTime };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function benchmarkSQLite() {
|
|
56
|
+
console.log('Benchmarking better-sqlite3 (In-Memory)...\n');
|
|
57
|
+
|
|
58
|
+
const db = new BetterSqlite3(':memory:');
|
|
59
|
+
db.exec('CREATE TABLE bench (key BLOB PRIMARY KEY, value BLOB)');
|
|
60
|
+
|
|
61
|
+
// INSERT with transaction
|
|
62
|
+
const startInsert = process.hrtime.bigint();
|
|
63
|
+
const insertStmt = db.prepare('INSERT INTO bench (key, value) VALUES (?, ?)');
|
|
64
|
+
const insertMany = db.transaction((rows) => {
|
|
65
|
+
for (const row of rows) {
|
|
66
|
+
insertStmt.run(row.key, row.value);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
const rows = [];
|
|
70
|
+
for (let i = 0; i < N; i++) {
|
|
71
|
+
rows.push({
|
|
72
|
+
key: Buffer.from(`key:${i}`),
|
|
73
|
+
value: Buffer.from(`value:${i}`)
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
insertMany(rows);
|
|
77
|
+
const endInsert = process.hrtime.bigint();
|
|
78
|
+
const insertTime = Number(endInsert - startInsert) / 1e9;
|
|
79
|
+
|
|
80
|
+
// GET
|
|
81
|
+
const startGet = process.hrtime.bigint();
|
|
82
|
+
const getStmt = db.prepare('SELECT value FROM bench WHERE key = ?');
|
|
83
|
+
for (let i = 0; i < N; i++) {
|
|
84
|
+
const key = Buffer.from(`key:${i}`);
|
|
85
|
+
getStmt.get(key);
|
|
86
|
+
}
|
|
87
|
+
const endGet = process.hrtime.bigint();
|
|
88
|
+
const getTime = Number(endGet - startGet) / 1e9;
|
|
89
|
+
|
|
90
|
+
// DELETE with transaction
|
|
91
|
+
const startDelete = process.hrtime.bigint();
|
|
92
|
+
const deleteStmt = db.prepare('DELETE FROM bench WHERE key = ?');
|
|
93
|
+
const deleteMany = db.transaction((keys) => {
|
|
94
|
+
for (const key of keys) {
|
|
95
|
+
deleteStmt.run(key);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
const keys = [];
|
|
99
|
+
for (let i = 0; i < N; i++) {
|
|
100
|
+
keys.push(Buffer.from(`key:${i}`));
|
|
101
|
+
}
|
|
102
|
+
deleteMany(keys);
|
|
103
|
+
const endDelete = process.hrtime.bigint();
|
|
104
|
+
const deleteTime = Number(endDelete - startDelete) / 1e9;
|
|
105
|
+
|
|
106
|
+
db.close();
|
|
107
|
+
|
|
108
|
+
return { insertTime, getTime, deleteTime };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function printResults(name, { insertTime, getTime, deleteTime }) {
|
|
112
|
+
console.log(`${name}:`);
|
|
113
|
+
console.log(` INSERT: ${insertTime.toFixed(4)}s (${Math.floor(N / insertTime).toLocaleString()} ops/sec)`);
|
|
114
|
+
console.log(` GET: ${getTime.toFixed(4)}s (${Math.floor(N / getTime).toLocaleString()} ops/sec)`);
|
|
115
|
+
console.log(` DELETE: ${deleteTime.toFixed(4)}s (${Math.floor(N / deleteTime).toLocaleString()} ops/sec)`);
|
|
116
|
+
console.log();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function main() {
|
|
120
|
+
console.log('='.repeat(60));
|
|
121
|
+
console.log('DBX Native (napi-rs) vs better-sqlite3 - Performance Comparison');
|
|
122
|
+
console.log('WITH BATCH API OPTIMIZATION');
|
|
123
|
+
console.log('='.repeat(60));
|
|
124
|
+
console.log(`\nRunning benchmarks with ${N.toLocaleString()} operations...\n`);
|
|
125
|
+
|
|
126
|
+
// Benchmark DBX
|
|
127
|
+
const dbxResults = benchmarkDBX();
|
|
128
|
+
printResults('DBX Native (napi-rs) with Batch API', dbxResults);
|
|
129
|
+
|
|
130
|
+
// Benchmark SQLite
|
|
131
|
+
const sqliteResults = benchmarkSQLite();
|
|
132
|
+
printResults('better-sqlite3 (In-Memory)', sqliteResults);
|
|
133
|
+
|
|
134
|
+
// Comparison
|
|
135
|
+
console.log('='.repeat(60));
|
|
136
|
+
console.log('Performance Comparison:');
|
|
137
|
+
console.log('='.repeat(60));
|
|
138
|
+
|
|
139
|
+
const insertRatio = sqliteResults.insertTime / dbxResults.insertTime;
|
|
140
|
+
const getRatio = sqliteResults.getTime / dbxResults.getTime;
|
|
141
|
+
const deleteRatio = sqliteResults.deleteTime / dbxResults.deleteTime;
|
|
142
|
+
|
|
143
|
+
if (insertRatio > 1) {
|
|
144
|
+
console.log(`INSERT: DBX is ${insertRatio.toFixed(2)}x faster`);
|
|
145
|
+
} else {
|
|
146
|
+
console.log(`INSERT: SQLite is ${(1 / insertRatio).toFixed(2)}x faster`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (getRatio > 1) {
|
|
150
|
+
console.log(`GET: DBX is ${getRatio.toFixed(2)}x faster`);
|
|
151
|
+
} else {
|
|
152
|
+
console.log(`GET: SQLite is ${(1 / getRatio).toFixed(2)}x faster`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (deleteRatio > 1) {
|
|
156
|
+
console.log(`DELETE: DBX is ${deleteRatio.toFixed(2)}x faster`);
|
|
157
|
+
} else {
|
|
158
|
+
console.log(`DELETE: SQLite is ${(1 / deleteRatio).toFixed(2)}x faster`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
console.log('\n' + '='.repeat(60));
|
|
162
|
+
console.log('Benchmark completed!');
|
|
163
|
+
console.log('='.repeat(60));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
main();
|