23f7624596
ADR-166 MCP Bridge Security Lock / Static-source security lock (push) Failing after 0s
ADR-166 MCP Bridge Security Lock / Compose default binds loopback + Mongo has auth (push) Failing after 2s
CodeQL Advanced / Analyze (rust) (push) Failing after 0s
ADR-166 MCP Bridge Security Lock / plugin-agent-federation bindHost default (push) Failing after 1s
ADR-166 MCP Bridge Security Lock / Runtime behavior — 401 + terminal gate + fail-closed (push) Failing after 4s
business-pods-smoke / smoke (push) Failing after 1s
all-plugins-smoke / smoke-all (push) Failing after 2s
CI/CD Pipeline / Security & Code Quality (push) Failing after 1s
CI/CD Pipeline / Test Suite (ubuntu-latest) (push) Failing after 1s
CI/CD Pipeline / Build & Package (macos-latest) (push) Has been skipped
CI/CD Pipeline / Build & Package (ubuntu-latest) (push) Has been skipped
CI/CD Pipeline / Build & Package (windows-latest) (push) Has been skipped
CI/CD Pipeline / Documentation & Examples (push) Failing after 1s
Clone Tracker (14-day rolling) / Snapshot clones for ruflo ecosystem (push) Failing after 1s
CodeQL Advanced / Analyze (actions) (push) Failing after 1s
CodeQL Advanced / Analyze (javascript-typescript) (push) Failing after 1s
federation-peer-rust / stable-noop (push) Failing after 1s
metaharness-ci / score (push) Failing after 1s
metaharness-ci / router-compat (push) Failing after 0s
metaharness-ci / similarity-tests (push) Failing after 0s
no-agentbbs-smoke / smoke-without-agentbbs (push) Failing after 1s
V3 CI/CD Pipeline / Build V3 (windows-latest) (push) Has been skipped
codex-integration-audit / Codex integration audit (push) Failing after 1s
helpers-manifest-guard / guard (push) Failing after 1s
🔗 Cross-Agent Integration Tests / 🤝 Agent Coordination Tests (push) Has been skipped
🔗 Cross-Agent Integration Tests / 🧠 Memory Sharing Integration (push) Has been skipped
🔗 Cross-Agent Integration Tests / 🛡️ Fault Tolerance Tests (push) Has been skipped
🔗 Cross-Agent Integration Tests / ⚡ Performance Integration Tests (push) Has been skipped
metaharness-ci / mcp-scan (push) Failing after 1s
metaharness-ci / eject-dryrun (push) Failing after 1s
metaharness-ci / metaharness-real-data (push) Failing after 0s
no-cli-optdep-bloat-2561 / guard (push) Failing after 1s
no-metaharness-smoke / smoke-without-metaharness (push) Failing after 1s
no-phantom-agentic-flow-subpath / guard (push) Failing after 1s
🔄 Automated Rollback Manager / 🚨 Failure Detection (push) Failing after 1s
V3 CI/CD Pipeline / Plugin hooks smoke / ubuntu-latest / Node 22 (push) Failing after 1s
V3 CI/CD Pipeline / ruflo-graph-intelligence build + test smoke (#2044, ADR-123) (push) Failing after 1s
CVE Audit Gate / Audit root (critical-blocking) (push) Failing after 2s
cost-tracker-smoke / smoke (push) Failing after 3s
oia-audit-weekly / audit (push) Failing after 2s
ruflo-agent-smoke / ruflo-agent structural smoke (push) Failing after 1s
📊 Status Badges Update / 📊 Update Status Badges (push) Failing after 1s
V3 CI/CD Pipeline / Static regression guards (#2267 YAML + (push) Failing after 1s
V3 CI/CD Pipeline / Test V3 Packages (push) Failing after 0s
V3 CI/CD Pipeline / agent_execute provider routing smoke (#2042) (push) Failing after 0s
CVE Audit Gate / Audit v3 (critical-blocking) (push) Failing after 1s
federation-peer-rust / stable-native (push) Failing after 2s
🔗 Cross-Agent Integration Tests / 🚀 Integration Test Setup (push) Failing after 2s
neural-trader-smoke / runtime-smoke (push) Failing after 1s
V3 CI/CD Pipeline / Build V3 (macos-latest) (push) Has been skipped
V3 CI/CD Pipeline / Build V3 (ubuntu-latest) (push) Has been skipped
V3 CI/CD Pipeline / Type Check V3 (push) Failing after 1s
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / ubuntu-latest / Node 24 (push) Failing after 1s
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / ubuntu-latest / Node 22 (push) Failing after 2s
V3 CI/CD Pipeline / browser rvf create flag smoke (#2015) (push) Failing after 0s
V3 CI/CD Pipeline / Dependency review (#2046) (push) Has been skipped
V3 CI/CD Pipeline / Supply-chain audit (#2046) (push) Failing after 0s
V3 CI/CD Pipeline / witness marker drift smoke (#2021) (push) Failing after 1s
V3 CI/CD Pipeline / neural-trader portfolio CG smoke (#2068, ADR-126 Phase 3) (push) Failing after 1s
V3 CI/CD Pipeline / neural-trader backtest signing smoke (#2068, ADR-126 Phase 4) (push) Failing after 1s
V3 CI/CD Pipeline / kg-extract type-import classification smoke (#2049) (push) Failing after 0s
V3 CI/CD Pipeline / witness verify precondition smoke (#1880) (push) Failing after 2s
V3 CI/CD Pipeline / neural-trader pipeline risk-gate smoke (#2068, ADR-126 Phase 5) (push) Failing after 0s
V3 CI/CD Pipeline / neural-trader feature attribution smoke (#2068, ADR-126 Phase 6) (push) Failing after 0s
V3 CI/CD Pipeline / plugin-registry signature verification smoke (#1922, CWE-347) (push) Failing after 4s
V3 CI/CD Pipeline / memory stats legacy-DB smoke (#2120) (push) Failing after 4s
V3 CI/CD Pipeline / github deprecated actions smoke (#2089, ADR-127 Phase 3) (push) Failing after 1s
V3 CI/CD Pipeline / graph query + pathfinder smoke (ADR-130 P2+P5) (push) Has been skipped
V3 CI/CD Pipeline / graph trajectory hooks smoke (ADR-130 P3) (push) Has been skipped
V3 CI/CD Pipeline / graph plugin adapter smoke (ADR-130 P4) (push) Has been skipped
V3 CI/CD Pipeline / graph benchmark (ADR-130 P6) (push) Has been skipped
V3 CI/CD Pipeline / statusline generator delegation smoke (#2195) (push) Failing after 1s
V3 CI/CD Pipeline / wizard init regression guard (#2206 (push) Failing after 1s
V3 CI/CD Pipeline / memory no-stray-db smoke (ADR-125 P7) (push) Failing after 1s
V3 CI/CD Pipeline / github-safe injection smoke (#2089, ADR-127 Phase 1) (push) Failing after 1s
V3 CI/CD Pipeline / github actions pin smoke (#2089, ADR-127 Phase 1) (push) Failing after 1s
V3 CI/CD Pipeline / github attribution opt-in smoke (#2089, ADR-127 Phase 4) (push) Failing after 1s
V3 CI/CD Pipeline / pre-bash hook safety smoke (#2017) (push) Failing after 1s
V3 CI/CD Pipeline / Memory import smoke / ubuntu-latest (push) Failing after 0s
V3 CI/CD Pipeline / MCP protocol smoke / ubuntu-latest (push) Failing after 2s
V3 CI/CD Pipeline / ruvllm WASM auto-init smoke (#2086) (push) Failing after 4s
V3 CI/CD Pipeline / MCP paired-tool round-trip smoke (#1889) (push) Failing after 1s
V3 CI/CD Pipeline / Plugin package install-safety (#1902/#1903/#1904) (push) Failing after 1s
V3 CI/CD Pipeline / Tool description discoverability (ADR-112) (push) Failing after 3s
V3 CI/CD Pipeline / CLI npx-install smoke (#1147 / (22) (push) Failing after 1s
V3 CI/CD Pipeline / CLI npx-install smoke (#1147 / (24) (push) Failing after 1s
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / ubuntu-latest (push) Failing after 2s
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / ubuntu-latest (push) Failing after 1s
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / ubuntu-latest (push) Failing after 1s
V3 CI/CD Pipeline / Vector-index dimension audit (#1947) (push) Failing after 0s
V3 CI/CD Pipeline / Hook-command install safety (#1921) (push) Failing after 1s
V3 CI/CD Pipeline / ToolOutputGuardrail smoke (ADR-131, (push) Failing after 1s
V3 CI/CD Pipeline / init-bundle invariants smoke (#2095, ADR-128 Phase 5) (push) Failing after 1s
V3 CI/CD Pipeline / wasm provider bridge smoke (ADR-129 P1) (push) Failing after 2s
V3 CI/CD Pipeline / wasm gallery CRUD smoke (ADR-129 P3) (push) Failing after 1s
V3 CI/CD Pipeline / wasm plugin bridge smoke (ADR-129 P4) (push) Failing after 0s
V3 CI/CD Pipeline / wasm compose smoke (ADR-129 P2) (push) Failing after 4s
V3 CI/CD Pipeline / graph schema smoke (ADR-130 P1) (push) Failing after 0s
Validate Marketplace / validate (push) Failing after 1s
🔍 Verification Pipeline / 🚀 Setup Verification (push) Failing after 1s
🔍 Verification Pipeline / 🛡️ Security Verification (push) Has been skipped
🔍 Verification Pipeline / 📝 Code Quality (push) Has been skipped
🔍 Verification Pipeline / 🧪 Test Verification (${{ matrix.os }}, Node ${{ matrix.node }}) (push) Has been skipped
🔍 Verification Pipeline / 🏗️ Build Verification (push) Has been skipped
🔍 Verification Pipeline / 📚 Documentation Verification (push) Has been skipped
CVE Audit Gate / High-severity report (warn only) (push) Has been cancelled
🔄 Automated Rollback Manager / 🔄 Execute Rollback (push) Has been cancelled
🔄 Automated Rollback Manager / ✅ Post-Rollback Verification (push) Has been cancelled
🔄 Automated Rollback Manager / 📊 Rollback Monitoring (push) Has been cancelled
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / windows-latest (push) Has been cancelled
🔄 Automated Rollback Manager / ⏳ Manual Rollback Approval (push) Has been cancelled
V3 CI/CD Pipeline / MCP protocol smoke / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Memory import smoke / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / ubuntu-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Publish to npm (alpha) (push) Has been cancelled
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / macos-latest / Node 22 (push) Has been cancelled
V3 CI/CD Pipeline / Plugin hooks smoke / macos-latest / Node 22 (push) Has been cancelled
CI/CD Pipeline / Deploy & Release (push) Has been cancelled
CI/CD Pipeline / CI Status (push) Has been cancelled
🔗 Cross-Agent Integration Tests / 📊 Integration Test Report (push) Has been cancelled
🔄 Automated Rollback Manager / 🔍 Pre-Rollback Validation (push) Has been cancelled
🔍 Verification Pipeline / ⚡ Performance Verification (push) Has been cancelled
🔍 Verification Pipeline / 📊 Verification Report (push) Has been cancelled
450 lines
13 KiB
TypeScript
450 lines
13 KiB
TypeScript
/**
|
|
* Vector Search Benchmark
|
|
*
|
|
* Target: <1ms (150x faster than current ~150ms)
|
|
*
|
|
* Measures vector similarity search performance including
|
|
* linear search baseline vs HNSW optimized search.
|
|
*/
|
|
|
|
import { benchmark, BenchmarkRunner, formatTime, meetsTarget } from '../framework/benchmark.js';
|
|
|
|
// ============================================================================
|
|
// Vector Operations
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Generate a random vector of specified dimension
|
|
*/
|
|
function generateVector(dimension: number): Float32Array {
|
|
const vector = new Float32Array(dimension);
|
|
for (let i = 0; i < dimension; i++) {
|
|
vector[i] = Math.random() * 2 - 1;
|
|
}
|
|
return normalizeVector(vector);
|
|
}
|
|
|
|
/**
|
|
* Normalize a vector to unit length
|
|
*/
|
|
function normalizeVector(vector: Float32Array): Float32Array {
|
|
let sum = 0;
|
|
for (let i = 0; i < vector.length; i++) {
|
|
sum += vector[i]! * vector[i]!;
|
|
}
|
|
const magnitude = Math.sqrt(sum);
|
|
if (magnitude > 0) {
|
|
for (let i = 0; i < vector.length; i++) {
|
|
vector[i]! /= magnitude;
|
|
}
|
|
}
|
|
return vector;
|
|
}
|
|
|
|
/**
|
|
* Calculate cosine similarity between two vectors
|
|
*/
|
|
function cosineSimilarity(a: Float32Array, b: Float32Array): number {
|
|
let dot = 0;
|
|
for (let i = 0; i < a.length; i++) {
|
|
dot += a[i]! * b[i]!;
|
|
}
|
|
return dot;
|
|
}
|
|
|
|
/**
|
|
* Calculate Euclidean distance between two vectors
|
|
*/
|
|
function euclideanDistance(a: Float32Array, b: Float32Array): number {
|
|
let sum = 0;
|
|
for (let i = 0; i < a.length; i++) {
|
|
const diff = a[i]! - b[i]!;
|
|
sum += diff * diff;
|
|
}
|
|
return Math.sqrt(sum);
|
|
}
|
|
|
|
// ============================================================================
|
|
// Search Implementations
|
|
// ============================================================================
|
|
|
|
interface SearchResult {
|
|
id: number;
|
|
score: number;
|
|
}
|
|
|
|
/**
|
|
* Linear (brute-force) search - O(n)
|
|
*/
|
|
function linearSearch(
|
|
query: Float32Array,
|
|
vectors: Float32Array[],
|
|
k: number
|
|
): SearchResult[] {
|
|
const scores: SearchResult[] = vectors.map((v, i) => ({
|
|
id: i,
|
|
score: cosineSimilarity(query, v),
|
|
}));
|
|
|
|
scores.sort((a, b) => b.score - a.score);
|
|
return scores.slice(0, k);
|
|
}
|
|
|
|
/**
|
|
* Simple HNSW-like graph for approximate nearest neighbors
|
|
* Simplified implementation for benchmarking
|
|
*/
|
|
class SimpleHNSW {
|
|
private vectors: Float32Array[] = [];
|
|
private graph: Map<number, number[]> = new Map();
|
|
private entryPoint = 0;
|
|
private readonly maxConnections = 16;
|
|
private readonly efConstruction = 100;
|
|
|
|
add(vector: Float32Array): number {
|
|
const id = this.vectors.length;
|
|
this.vectors.push(vector);
|
|
|
|
if (id === 0) {
|
|
this.graph.set(id, []);
|
|
return id;
|
|
}
|
|
|
|
// Find nearest neighbors using current graph
|
|
const neighbors = this.searchLayer(vector, this.entryPoint, this.efConstruction);
|
|
|
|
// Connect to nearest neighbors
|
|
const connections = neighbors
|
|
.slice(0, this.maxConnections)
|
|
.map((r) => r.id);
|
|
this.graph.set(id, connections);
|
|
|
|
// Add reverse connections
|
|
for (const neighborId of connections) {
|
|
const neighborConnections = this.graph.get(neighborId) || [];
|
|
if (neighborConnections.length < this.maxConnections) {
|
|
neighborConnections.push(id);
|
|
this.graph.set(neighborId, neighborConnections);
|
|
}
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
search(query: Float32Array, k: number, ef = 50): SearchResult[] {
|
|
if (this.vectors.length === 0) return [];
|
|
|
|
const results = this.searchLayer(query, this.entryPoint, Math.max(k, ef));
|
|
return results.slice(0, k);
|
|
}
|
|
|
|
private searchLayer(
|
|
query: Float32Array,
|
|
entryPoint: number,
|
|
ef: number
|
|
): SearchResult[] {
|
|
const visited = new Set<number>();
|
|
const candidates: SearchResult[] = [
|
|
{ id: entryPoint, score: cosineSimilarity(query, this.vectors[entryPoint]!) },
|
|
];
|
|
const results: SearchResult[] = [...candidates];
|
|
|
|
visited.add(entryPoint);
|
|
|
|
while (candidates.length > 0) {
|
|
candidates.sort((a, b) => b.score - a.score);
|
|
const current = candidates.shift()!;
|
|
|
|
const neighbors = this.graph.get(current.id) || [];
|
|
for (const neighborId of neighbors) {
|
|
if (visited.has(neighborId)) continue;
|
|
visited.add(neighborId);
|
|
|
|
const score = cosineSimilarity(query, this.vectors[neighborId]!);
|
|
results.push({ id: neighborId, score });
|
|
candidates.push({ id: neighborId, score });
|
|
|
|
if (results.length > ef) {
|
|
results.sort((a, b) => b.score - a.score);
|
|
results.length = ef;
|
|
}
|
|
}
|
|
|
|
if (candidates.length > ef) {
|
|
candidates.sort((a, b) => b.score - a.score);
|
|
candidates.length = ef;
|
|
}
|
|
}
|
|
|
|
results.sort((a, b) => b.score - a.score);
|
|
return results;
|
|
}
|
|
|
|
get size(): number {
|
|
return this.vectors.length;
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Benchmark Suite
|
|
// ============================================================================
|
|
|
|
export async function runVectorSearchBenchmarks(): Promise<void> {
|
|
const runner = new BenchmarkRunner('Vector Search');
|
|
|
|
console.log('\n--- Vector Search Benchmarks ---\n');
|
|
|
|
const dimensions = 384; // Common embedding dimension
|
|
const k = 10; // Number of results to return
|
|
|
|
// Prepare test data
|
|
console.log('Preparing test data...');
|
|
|
|
// Small dataset (1,000 vectors)
|
|
const smallDataset = Array.from({ length: 1000 }, () => generateVector(dimensions));
|
|
const smallHNSW = new SimpleHNSW();
|
|
for (const v of smallDataset) {
|
|
smallHNSW.add(v);
|
|
}
|
|
|
|
// Medium dataset (10,000 vectors)
|
|
const mediumDataset = Array.from({ length: 10000 }, () => generateVector(dimensions));
|
|
const mediumHNSW = new SimpleHNSW();
|
|
for (const v of mediumDataset) {
|
|
mediumHNSW.add(v);
|
|
}
|
|
|
|
// Query vector
|
|
const query = generateVector(dimensions);
|
|
|
|
console.log('Test data prepared.\n');
|
|
|
|
// Benchmark 1: Linear Search - 1,000 vectors
|
|
const linear1kResult = await runner.run(
|
|
'linear-search-1k',
|
|
async () => {
|
|
linearSearch(query, smallDataset, k);
|
|
},
|
|
{ iterations: 100 }
|
|
);
|
|
|
|
console.log(`Linear Search (1k vectors): ${formatTime(linear1kResult.mean)}`);
|
|
|
|
// Benchmark 2: HNSW Search - 1,000 vectors
|
|
const hnsw1kResult = await runner.run(
|
|
'hnsw-search-1k',
|
|
async () => {
|
|
smallHNSW.search(query, k);
|
|
},
|
|
{ iterations: 500 }
|
|
);
|
|
|
|
console.log(`HNSW Search (1k vectors): ${formatTime(hnsw1kResult.mean)}`);
|
|
const speedup1k = linear1kResult.mean / hnsw1kResult.mean;
|
|
console.log(` Speedup: ${speedup1k.toFixed(1)}x`);
|
|
|
|
// Benchmark 3: Linear Search - 10,000 vectors
|
|
const linear10kResult = await runner.run(
|
|
'linear-search-10k',
|
|
async () => {
|
|
linearSearch(query, mediumDataset, k);
|
|
},
|
|
{ iterations: 20 }
|
|
);
|
|
|
|
console.log(`Linear Search (10k vectors): ${formatTime(linear10kResult.mean)}`);
|
|
|
|
// Benchmark 4: HNSW Search - 10,000 vectors
|
|
const hnsw10kResult = await runner.run(
|
|
'hnsw-search-10k',
|
|
async () => {
|
|
mediumHNSW.search(query, k);
|
|
},
|
|
{ iterations: 200 }
|
|
);
|
|
|
|
console.log(`HNSW Search (10k vectors): ${formatTime(hnsw10kResult.mean)}`);
|
|
const speedup10k = linear10kResult.mean / hnsw10kResult.mean;
|
|
console.log(` Speedup: ${speedup10k.toFixed(1)}x`);
|
|
|
|
// Check target
|
|
const target = meetsTarget('vector-search', hnsw10kResult.mean);
|
|
console.log(` Target (<1ms): ${target.met ? 'PASS' : 'FAIL'}`);
|
|
|
|
// Benchmark 5: Cosine Similarity Calculation
|
|
const v1 = generateVector(dimensions);
|
|
const v2 = generateVector(dimensions);
|
|
|
|
const cosineResult = await runner.run(
|
|
'cosine-similarity',
|
|
async () => {
|
|
cosineSimilarity(v1, v2);
|
|
},
|
|
{ iterations: 10000 }
|
|
);
|
|
|
|
console.log(`Cosine Similarity: ${formatTime(cosineResult.mean)}`);
|
|
|
|
// Benchmark 6: Euclidean Distance Calculation
|
|
const euclideanResult = await runner.run(
|
|
'euclidean-distance',
|
|
async () => {
|
|
euclideanDistance(v1, v2);
|
|
},
|
|
{ iterations: 10000 }
|
|
);
|
|
|
|
console.log(`Euclidean Distance: ${formatTime(euclideanResult.mean)}`);
|
|
|
|
// Benchmark 7: Vector Normalization
|
|
const normResult = await runner.run(
|
|
'vector-normalization',
|
|
async () => {
|
|
const v = new Float32Array(dimensions);
|
|
for (let i = 0; i < dimensions; i++) {
|
|
v[i] = Math.random();
|
|
}
|
|
normalizeVector(v);
|
|
},
|
|
{ iterations: 5000 }
|
|
);
|
|
|
|
console.log(`Vector Normalization: ${formatTime(normResult.mean)}`);
|
|
|
|
// Benchmark 8: Batch Search (5 queries)
|
|
const queries = Array.from({ length: 5 }, () => generateVector(dimensions));
|
|
|
|
const batchSearchResult = await runner.run(
|
|
'batch-search-5-queries',
|
|
async () => {
|
|
for (const q of queries) {
|
|
smallHNSW.search(q, k);
|
|
}
|
|
},
|
|
{ iterations: 100 }
|
|
);
|
|
|
|
console.log(`Batch Search (5 queries): ${formatTime(batchSearchResult.mean)}`);
|
|
|
|
// Benchmark 9: Parallel Batch Search
|
|
const parallelBatchResult = await runner.run(
|
|
'parallel-batch-search',
|
|
async () => {
|
|
await Promise.all(queries.map((q) => Promise.resolve(smallHNSW.search(q, k))));
|
|
},
|
|
{ iterations: 100 }
|
|
);
|
|
|
|
console.log(`Parallel Batch Search: ${formatTime(parallelBatchResult.mean)}`);
|
|
|
|
// Summary
|
|
console.log('\n--- Summary ---');
|
|
console.log(`1k vectors: Linear ${formatTime(linear1kResult.mean)} -> HNSW ${formatTime(hnsw1kResult.mean)} (${speedup1k.toFixed(1)}x)`);
|
|
console.log(`10k vectors: Linear ${formatTime(linear10kResult.mean)} -> HNSW ${formatTime(hnsw10kResult.mean)} (${speedup10k.toFixed(1)}x)`);
|
|
console.log(`\nProjected for 100k vectors: ~${((speedup10k * 10)).toFixed(0)}x improvement`);
|
|
console.log(`Projected for 1M vectors: ~${((speedup10k * 100)).toFixed(0)}x improvement`);
|
|
|
|
// Print full results
|
|
runner.printResults();
|
|
}
|
|
|
|
// ============================================================================
|
|
// Vector Search Optimization Strategies
|
|
// ============================================================================
|
|
|
|
export const vectorSearchOptimizations = {
|
|
/**
|
|
* HNSW Indexing: Hierarchical Navigable Small World graphs
|
|
*/
|
|
hnswIndexing: {
|
|
description: 'Use HNSW for O(log n) approximate nearest neighbor search',
|
|
expectedImprovement: '150x-12500x',
|
|
implementation: `
|
|
import { HNSW } from 'agentdb';
|
|
|
|
const index = new HNSW({
|
|
dimensions: 384,
|
|
maxElements: 1000000,
|
|
efConstruction: 200,
|
|
M: 16,
|
|
});
|
|
|
|
index.addItems(vectors);
|
|
const results = index.search(query, k);
|
|
`,
|
|
},
|
|
|
|
/**
|
|
* SIMD Operations: Use SIMD for vector math
|
|
*/
|
|
simdOperations: {
|
|
description: 'Use SIMD instructions for parallel vector operations',
|
|
expectedImprovement: '4-8x',
|
|
implementation: `
|
|
// Use typed arrays and native SIMD when available
|
|
function dotProductSIMD(a: Float32Array, b: Float32Array): number {
|
|
// Node.js will use SIMD when available
|
|
let sum = 0;
|
|
for (let i = 0; i < a.length; i += 4) {
|
|
sum += a[i] * b[i] + a[i+1] * b[i+1] + a[i+2] * b[i+2] + a[i+3] * b[i+3];
|
|
}
|
|
return sum;
|
|
}
|
|
`,
|
|
},
|
|
|
|
/**
|
|
* Quantization: Use int8 instead of float32
|
|
*/
|
|
quantization: {
|
|
description: 'Quantize vectors to int8 for 4x memory savings and faster ops',
|
|
expectedImprovement: '2-4x speed, 4x memory',
|
|
implementation: `
|
|
function quantize(vector: Float32Array): Int8Array {
|
|
const quantized = new Int8Array(vector.length);
|
|
for (let i = 0; i < vector.length; i++) {
|
|
quantized[i] = Math.round(vector[i] * 127);
|
|
}
|
|
return quantized;
|
|
}
|
|
`,
|
|
},
|
|
|
|
/**
|
|
* Batch Processing: Process multiple queries together
|
|
*/
|
|
batchProcessing: {
|
|
description: 'Process multiple queries in a single batch for better cache utilization',
|
|
expectedImprovement: '2-5x',
|
|
implementation: `
|
|
async function batchSearch(queries: Float32Array[], k: number): Promise<SearchResult[][]> {
|
|
// Process all queries together for better cache locality
|
|
return queries.map(q => index.search(q, k));
|
|
}
|
|
`,
|
|
},
|
|
|
|
/**
|
|
* Pre-filtering: Reduce search space with metadata filters
|
|
*/
|
|
preFiltering: {
|
|
description: 'Use metadata filters to reduce the search space before vector search',
|
|
expectedImprovement: '2-10x',
|
|
implementation: `
|
|
function filteredSearch(query: Float32Array, filter: Filter, k: number): SearchResult[] {
|
|
// First apply metadata filter
|
|
const candidates = applyFilter(filter);
|
|
// Then search only within filtered candidates
|
|
return searchWithinCandidates(query, candidates, k);
|
|
}
|
|
`,
|
|
},
|
|
};
|
|
|
|
// Run if executed directly
|
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
runVectorSearchBenchmarks().catch(console.error);
|
|
}
|
|
|
|
export default runVectorSearchBenchmarks;
|