UNPKG

milodb

Version:

A simple mini database with optional encryption to store key-value pairs

143 lines (120 loc) 5.38 kB
const fs = require('fs').promises; const path = require('path'); const MinoDB = require('../src/index'); const BENCHMARK_DB_PATH = path.join(__dirname, '..', 'db', 'benchmark-db.json'); const NUM_ROWS = 1_000_000; const SEARCH_SAMPLES = 1000; // Number of search operations to perform const EDIT_SAMPLES = 1000; // Number of edit operations to perform async function runSearchEditBenchmark() { console.log('Starting Search and Edit Benchmark...\n'); // Initialize database const db = new MinoDB(null, false); db.dbPath = BENCHMARK_DB_PATH; // Generate test data if it doesn't exist if (!await fileExists(BENCHMARK_DB_PATH)) { console.log(`Creating test database with ${NUM_ROWS.toLocaleString()} entries...`); for (let i = 0; i < NUM_ROWS; i++) { await db.set(`key${i}`, `value${i}`); if (i > 0 && i % 100_000 === 0) { console.log(` Inserted ${i.toLocaleString()} entries...`); } } } // Benchmark Search Operations console.log('\nBenchmarking Search Operations...'); const searchTimes = []; const searchPatterns = [ 'value1', // Common prefix '999', // Common suffix '500', // Middle value 'key1', // Key search 'nonexistent' // No matches ]; for (const pattern of searchPatterns) { console.log(`\nSearching for pattern: "${pattern}"`); // Basic search const basicStart = Date.now(); const basicResults = await db.search(pattern); const basicTime = Date.now() - basicStart; searchTimes.push({ pattern, type: 'basic', time: basicTime, results: Object.keys(basicResults).length }); console.log(` Basic search: ${basicTime}ms, found ${Object.keys(basicResults).length} results`); // Regex search const regexStart = Date.now(); const regexResults = await db.search(pattern, { regex: true }); const regexTime = Date.now() - regexStart; searchTimes.push({ pattern, type: 'regex', time: regexTime, results: Object.keys(regexResults).length }); console.log(` Regex search: ${regexTime}ms, found ${Object.keys(regexResults).length} results`); // Case-sensitive search const caseStart = Date.now(); const caseResults = await db.search(pattern.toUpperCase(), { caseSensitive: true }); const caseTime = Date.now() - caseStart; searchTimes.push({ pattern, type: 'case-sensitive', time: caseTime, results: Object.keys(caseResults).length }); console.log(` Case-sensitive search: ${caseTime}ms, found ${Object.keys(caseResults).length} results`); } // Benchmark Edit Operations console.log('\nBenchmarking Edit Operations...'); const editTimes = []; // Random edits for (let i = 0; i < EDIT_SAMPLES; i++) { const key = `key${Math.floor(Math.random() * NUM_ROWS)}`; const newValue = `updated_value_${i}`; const start = Date.now(); await db.set(key, newValue); const time = Date.now() - start; editTimes.push(time); if (i % 100 === 0) { console.log(` Completed ${i} edits...`); } } // Batch edits console.log('\nBenchmarking Batch Edit Operations...'); const batchSize = 100; const batchTimes = []; for (let i = 0; i < EDIT_SAMPLES / batchSize; i++) { const operations = []; for (let j = 0; j < batchSize; j++) { const key = `key${Math.floor(Math.random() * NUM_ROWS)}`; operations.push({ type: 'set', key, value: `batch_updated_${i}_${j}` }); } const start = Date.now(); await db.batch(operations); const time = Date.now() - start; batchTimes.push(time); console.log(` Completed batch ${i + 1}...`); } // Print Results console.log('\nBenchmark Results:'); console.log('\nSearch Operations:'); searchTimes.forEach(({ pattern, type, time, results }) => { console.log(` ${type} search for "${pattern}": ${time}ms, found ${results} results`); }); console.log('\nEdit Operations:'); const avgEditTime = editTimes.reduce((a, b) => a + b, 0) / editTimes.length; console.log(` Average single edit time: ${avgEditTime.toFixed(2)}ms`); console.log('\nBatch Edit Operations:'); const avgBatchTime = batchTimes.reduce((a, b) => a + b, 0) / batchTimes.length; console.log(` Average batch edit time (${batchSize} operations): ${avgBatchTime.toFixed(2)}ms`); console.log(` Average time per operation in batch: ${(avgBatchTime / batchSize).toFixed(2)}ms`); // Memory Usage const mem = process.memoryUsage(); console.log('\nMemory Usage:'); console.log(` RSS: ${(mem.rss / 1024 / 1024).toFixed(2)} MB`); console.log(` Heap Total: ${(mem.heapTotal / 1024 / 1024).toFixed(2)} MB`); console.log(` Heap Used: ${(mem.heapUsed / 1024 / 1024).toFixed(2)} MB`); } async function fileExists(path) { try { await fs.access(path); return true; } catch { return false; } } runSearchEditBenchmark().catch(err => { console.error('Benchmark failed:', err); process.exit(1); });