agentdb 1.0.10 ā 1.0.12
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/bin/agentdb.js +48 -43
- package/bin/benchmark.js +165 -0
- package/package.json +1 -1
package/bin/agentdb.js
CHANGED
|
@@ -402,59 +402,64 @@ function initDatabase(path) {
|
|
|
402
402
|
}
|
|
403
403
|
}
|
|
404
404
|
|
|
405
|
-
function runBenchmark() {
|
|
406
|
-
console.log('š Running AgentDB Performance Benchmarks...');
|
|
407
|
-
console.log('');
|
|
408
|
-
console.log('This will test:');
|
|
409
|
-
console.log(' - Native & WASM backend performance');
|
|
410
|
-
console.log(' - Insert operations (single & batch)');
|
|
411
|
-
console.log(' - Search operations (various metrics)');
|
|
412
|
-
console.log(' - Memory usage');
|
|
413
|
-
console.log(' - Backend comparison');
|
|
414
|
-
console.log('');
|
|
415
|
-
|
|
405
|
+
async function runBenchmark(...args) {
|
|
416
406
|
try {
|
|
417
|
-
//
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
const
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
407
|
+
// Convert arguments to array
|
|
408
|
+
const argArray = Array.isArray(args[0]) ? args[0] : Array.from(args);
|
|
409
|
+
|
|
410
|
+
// Parse arguments
|
|
411
|
+
const options = {
|
|
412
|
+
quick: argArray.includes('--quick') || argArray.includes('-q'),
|
|
413
|
+
vectors: null
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
// Parse custom vector count
|
|
417
|
+
const vectorsIndex = argArray.findIndex(arg => arg === '--vectors' || arg === '-v');
|
|
418
|
+
if (vectorsIndex !== -1 && argArray[vectorsIndex + 1]) {
|
|
419
|
+
options.vectors = parseInt(argArray[vectorsIndex + 1], 10);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// Show help if requested
|
|
423
|
+
if (argArray.includes('--help') || argArray.includes('-h')) {
|
|
424
|
+
console.log('');
|
|
425
|
+
console.log('AgentDB Benchmark');
|
|
426
|
+
console.log('');
|
|
427
|
+
console.log('USAGE');
|
|
428
|
+
console.log(' npx agentdb benchmark [options]');
|
|
429
|
+
console.log('');
|
|
430
|
+
console.log('OPTIONS');
|
|
431
|
+
console.log(' --quick, -q Run quick benchmark (~5 seconds, 300 vectors)');
|
|
432
|
+
console.log(' --vectors, -v <n> Custom batch size (default: 1000, quick: 300)');
|
|
433
|
+
console.log(' --help, -h Show this help');
|
|
434
|
+
console.log('');
|
|
435
|
+
console.log('EXAMPLES');
|
|
436
|
+
console.log(' npx agentdb benchmark # Standard benchmark (1K vectors, ~20s)');
|
|
437
|
+
console.log(' npx agentdb benchmark --quick # Quick benchmark (300 vectors, ~5s)');
|
|
438
|
+
console.log(' npx agentdb benchmark -v 2000 # Custom 2K vectors (~60s)');
|
|
439
|
+
console.log('');
|
|
440
|
+
console.log('For comprehensive benchmarks with WASM comparison:');
|
|
441
|
+
console.log(' git clone https://github.com/ruvnet/agentic-flow.git');
|
|
442
|
+
console.log(' cd agentic-flow/packages/agentdb');
|
|
443
|
+
console.log(' npm install && npm run bench:comprehensive');
|
|
444
|
+
console.log('');
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Run the included benchmark
|
|
449
|
+
const benchmarkPath = require.resolve('./benchmark.js');
|
|
450
|
+
const { runBenchmark } = require(benchmarkPath);
|
|
451
|
+
await runBenchmark(options);
|
|
431
452
|
} catch (error) {
|
|
432
|
-
// Benchmarks are not included in npm package
|
|
433
453
|
console.error('');
|
|
434
|
-
console.error('ā
|
|
454
|
+
console.error('ā Benchmark failed:', error.message);
|
|
435
455
|
console.error('');
|
|
436
|
-
console.error('
|
|
456
|
+
console.error('For comprehensive benchmarks, clone the source repository:');
|
|
437
457
|
console.error('');
|
|
438
458
|
console.error(' git clone https://github.com/ruvnet/agentic-flow.git');
|
|
439
459
|
console.error(' cd agentic-flow/packages/agentdb');
|
|
440
460
|
console.error(' npm install');
|
|
441
461
|
console.error(' npm run bench:comprehensive');
|
|
442
462
|
console.error('');
|
|
443
|
-
console.error('Or create a custom benchmark script:');
|
|
444
|
-
console.error('');
|
|
445
|
-
console.error(' const { SQLiteVectorDB } = require("agentdb");');
|
|
446
|
-
console.error(' const db = new SQLiteVectorDB({ memoryMode: true });');
|
|
447
|
-
console.error(' ');
|
|
448
|
-
console.error(' // Insert test vectors');
|
|
449
|
-
console.error(' const vectors = Array.from({ length: 1000 }, () => ({');
|
|
450
|
-
console.error(' embedding: Array(128).fill(0).map(() => Math.random()),');
|
|
451
|
-
console.error(' metadata: { test: true }');
|
|
452
|
-
console.error(' }));');
|
|
453
|
-
console.error(' ');
|
|
454
|
-
console.error(' const start = Date.now();');
|
|
455
|
-
console.error(' vectors.forEach(v => db.insert(v));');
|
|
456
|
-
console.error(' console.log(`Inserted 1000 vectors in ${Date.now() - start}ms`);');
|
|
457
|
-
console.error('');
|
|
458
463
|
process.exit(1);
|
|
459
464
|
}
|
|
460
465
|
}
|
package/bin/benchmark.js
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* AgentDB Quick Benchmark
|
|
4
|
+
* Simple performance test that works with the published npm package
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { performance } = require('perf_hooks');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Format throughput for display
|
|
11
|
+
*/
|
|
12
|
+
function formatThroughput(opsPerSec) {
|
|
13
|
+
if (opsPerSec >= 1000000) {
|
|
14
|
+
return `${(opsPerSec / 1000000).toFixed(2)}M/sec`;
|
|
15
|
+
} else if (opsPerSec >= 1000) {
|
|
16
|
+
return `${(opsPerSec / 1000).toFixed(2)}K/sec`;
|
|
17
|
+
} else {
|
|
18
|
+
return `${opsPerSec.toFixed(2)}/sec`;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Generate random vectors for testing
|
|
24
|
+
*/
|
|
25
|
+
function generateVectors(count, dimensions = 128) {
|
|
26
|
+
const vectors = [];
|
|
27
|
+
for (let i = 0; i < count; i++) {
|
|
28
|
+
vectors.push({
|
|
29
|
+
id: `vec-${i}`,
|
|
30
|
+
embedding: Array.from({ length: dimensions }, () => Math.random()),
|
|
31
|
+
metadata: {
|
|
32
|
+
index: i,
|
|
33
|
+
category: `cat-${i % 10}`,
|
|
34
|
+
timestamp: Date.now()
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return vectors;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Run benchmark suite
|
|
43
|
+
*/
|
|
44
|
+
async function runBenchmark(options = {}) {
|
|
45
|
+
const { quick = false, vectors = null } = options;
|
|
46
|
+
|
|
47
|
+
// Determine test sizes based on mode
|
|
48
|
+
// Note: HNSW index building is O(n log n), so batch sizes > 2000 can be slow
|
|
49
|
+
const sizes = quick ? {
|
|
50
|
+
single: 200,
|
|
51
|
+
batch: 300,
|
|
52
|
+
queries: 10
|
|
53
|
+
} : {
|
|
54
|
+
single: 500,
|
|
55
|
+
batch: vectors || 1000,
|
|
56
|
+
queries: 20
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
console.log('š AgentDB Performance Benchmark\n');
|
|
60
|
+
console.log(`Mode: ${quick ? 'Quick' : 'Standard'}`);
|
|
61
|
+
console.log('Testing Native SQLite backend with vector operations...\n');
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
const { SQLiteVectorDB } = require('../dist/index.js');
|
|
65
|
+
|
|
66
|
+
// Test 1: Database Initialization
|
|
67
|
+
console.log('š Test 1: Database Initialization');
|
|
68
|
+
const initStart = performance.now();
|
|
69
|
+
const db = new SQLiteVectorDB({ memoryMode: true });
|
|
70
|
+
const initDuration = performance.now() - initStart;
|
|
71
|
+
console.log(` ā
Initialized in ${initDuration.toFixed(2)}ms\n`);
|
|
72
|
+
|
|
73
|
+
// Test 2: Single Insert Performance
|
|
74
|
+
console.log(`š Test 2: Single Insert (${sizes.single.toLocaleString()} vectors)`);
|
|
75
|
+
const singleVectors = generateVectors(sizes.single, 128);
|
|
76
|
+
const singleStart = performance.now();
|
|
77
|
+
for (const vector of singleVectors) {
|
|
78
|
+
db.insert(vector);
|
|
79
|
+
}
|
|
80
|
+
const singleDuration = performance.now() - singleStart;
|
|
81
|
+
const singleOps = (sizes.single / singleDuration) * 1000;
|
|
82
|
+
console.log(` ā
Duration: ${singleDuration.toFixed(2)}ms`);
|
|
83
|
+
console.log(` ā
Throughput: ${formatThroughput(singleOps)}\n`);
|
|
84
|
+
|
|
85
|
+
// Close and recreate database for next test
|
|
86
|
+
db.close();
|
|
87
|
+
const db2 = new SQLiteVectorDB({ memoryMode: true });
|
|
88
|
+
|
|
89
|
+
// Test 3: Batch Insert Performance
|
|
90
|
+
console.log(`š Test 3: Batch Insert (${sizes.batch.toLocaleString()} vectors)`);
|
|
91
|
+
console.log(` ā³ Generating ${sizes.batch.toLocaleString()} random vectors...`);
|
|
92
|
+
const batchVectors = generateVectors(sizes.batch, 128);
|
|
93
|
+
console.log(` ā³ Inserting batch (this may take a moment for HNSW indexing)...`);
|
|
94
|
+
const batchStart = performance.now();
|
|
95
|
+
db2.insertBatch(batchVectors);
|
|
96
|
+
const batchDuration = performance.now() - batchStart;
|
|
97
|
+
const batchOps = (sizes.batch / batchDuration) * 1000;
|
|
98
|
+
console.log(` ā
Duration: ${batchDuration.toFixed(2)}ms (includes HNSW index building)`);
|
|
99
|
+
console.log(` ā
Throughput: ${formatThroughput(batchOps)}\n`);
|
|
100
|
+
|
|
101
|
+
// Test 4: Search Performance
|
|
102
|
+
console.log(`š Test 4: Vector Search (${sizes.queries} queries on ${sizes.batch.toLocaleString()} vectors)`);
|
|
103
|
+
const queryVector = Array.from({ length: 128 }, () => Math.random());
|
|
104
|
+
const searchStart = performance.now();
|
|
105
|
+
for (let i = 0; i < sizes.queries; i++) {
|
|
106
|
+
db2.search(queryVector, 10, 'cosine');
|
|
107
|
+
}
|
|
108
|
+
const searchDuration = performance.now() - searchStart;
|
|
109
|
+
const avgSearchLatency = searchDuration / sizes.queries;
|
|
110
|
+
console.log(` ā
Total: ${searchDuration.toFixed(2)}ms`);
|
|
111
|
+
console.log(` ā
Average: ${avgSearchLatency.toFixed(2)}ms per query\n`);
|
|
112
|
+
|
|
113
|
+
// Test 5: Different Similarity Metrics
|
|
114
|
+
console.log(`š Test 5: Similarity Metrics Comparison (${sizes.batch.toLocaleString()} vectors)`);
|
|
115
|
+
const metrics = ['cosine', 'euclidean', 'dot'];
|
|
116
|
+
for (const metric of metrics) {
|
|
117
|
+
const metricStart = performance.now();
|
|
118
|
+
for (let i = 0; i < sizes.queries; i++) {
|
|
119
|
+
db2.search(queryVector, 10, metric);
|
|
120
|
+
}
|
|
121
|
+
const metricDuration = performance.now() - metricStart;
|
|
122
|
+
console.log(` ā
${metric}: ${(metricDuration / sizes.queries).toFixed(2)}ms per query`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Test 6: Database Stats
|
|
126
|
+
console.log('\nš Test 6: Database Statistics');
|
|
127
|
+
const stats = db2.stats();
|
|
128
|
+
console.log(` ā
Total Vectors: ${stats.count.toLocaleString()}`);
|
|
129
|
+
console.log(` ā
DB Size: ${(stats.size / 1024 / 1024).toFixed(2)} MB`);
|
|
130
|
+
console.log(` ā
Size per 1K vectors: ${((stats.size / stats.count) * 1000 / 1024 / 1024).toFixed(3)} MB\n`);
|
|
131
|
+
|
|
132
|
+
db2.close();
|
|
133
|
+
|
|
134
|
+
// Print Summary
|
|
135
|
+
console.log('\n\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
136
|
+
console.log('š BENCHMARK SUMMARY');
|
|
137
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
138
|
+
|
|
139
|
+
console.log('Insert Performance:');
|
|
140
|
+
console.log(` - Single Insert: ${formatThroughput(singleOps)}`);
|
|
141
|
+
console.log(` - Batch ${sizes.batch.toLocaleString()}: ${formatThroughput(batchOps)}`);
|
|
142
|
+
|
|
143
|
+
console.log('\nSearch Performance:');
|
|
144
|
+
console.log(` - ${sizes.batch.toLocaleString()} vectors: ${avgSearchLatency.toFixed(2)}ms/query`);
|
|
145
|
+
|
|
146
|
+
console.log('\nMemory Efficiency:');
|
|
147
|
+
console.log(` - Size per 1K vectors: ${((stats.size / stats.count) * 1000 / 1024 / 1024).toFixed(3)} MB`);
|
|
148
|
+
|
|
149
|
+
console.log('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
150
|
+
console.log('ā
Benchmark completed successfully!\n');
|
|
151
|
+
|
|
152
|
+
process.exit(0);
|
|
153
|
+
} catch (error) {
|
|
154
|
+
console.error('\nā Benchmark failed:', error.message);
|
|
155
|
+
console.error('\nStack trace:', error.stack);
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Run if executed directly
|
|
161
|
+
if (require.main === module) {
|
|
162
|
+
runBenchmark();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
module.exports = { runBenchmark };
|
package/package.json
CHANGED