Files
wifi-densepose/vendor/ruvector/npm/packages/graph-node/benchmark.js

217 lines
8.9 KiB
JavaScript

/**
* RuVector Graph Node Benchmark
*
* Tests performance of graph operations including:
* - Node creation
* - Edge creation
* - Hyperedge creation
* - Batch inserts
* - Vector similarity search
* - k-hop neighbor traversal
* - Cypher queries
*/
const { GraphDatabase, version } = require('./index.js');
const DIMENSIONS = 384;
const NUM_NODES = 10000;
const NUM_EDGES = 50000;
const NUM_HYPEREDGES = 5000;
const SEARCH_K = 10;
function randomEmbedding(dims) {
const arr = new Float32Array(dims);
for (let i = 0; i < dims; i++) {
arr[i] = Math.random();
}
return arr;
}
function formatTime(ms) {
if (ms < 1) return `${(ms * 1000).toFixed(2)}μs`;
if (ms < 1000) return `${ms.toFixed(2)}ms`;
return `${(ms / 1000).toFixed(2)}s`;
}
function formatOps(count, ms) {
const ops = (count / ms) * 1000;
if (ops >= 1000000) return `${(ops / 1000000).toFixed(2)}M ops/sec`;
if (ops >= 1000) return `${(ops / 1000).toFixed(2)}K ops/sec`;
return `${ops.toFixed(2)} ops/sec`;
}
async function benchmark() {
console.log('╔════════════════════════════════════════════════════════════════╗');
console.log('║ RuVector Graph Node Benchmark Suite ║');
console.log('╠════════════════════════════════════════════════════════════════╣');
console.log(`║ Version: ${version().padEnd(54)}`);
console.log(`║ Dimensions: ${DIMENSIONS.toString().padEnd(51)}`);
console.log(`║ Nodes: ${NUM_NODES.toLocaleString().padEnd(56)}`);
console.log(`║ Edges: ${NUM_EDGES.toLocaleString().padEnd(56)}`);
console.log(`║ Hyperedges: ${NUM_HYPEREDGES.toLocaleString().padEnd(51)}`);
console.log('╚════════════════════════════════════════════════════════════════╝\n');
const db = new GraphDatabase({
distanceMetric: 'Cosine',
dimensions: DIMENSIONS
});
const results = [];
// Benchmark 1: Node Creation
console.log('📌 Benchmark 1: Individual Node Creation');
const nodeCount = 1000;
const nodeStart = performance.now();
for (let i = 0; i < nodeCount; i++) {
await db.createNode({
id: `node_${i}`,
embedding: randomEmbedding(DIMENSIONS),
labels: ['TestNode'],
properties: { index: String(i) }
});
}
const nodeEnd = performance.now();
const nodeTime = nodeEnd - nodeStart;
console.log(` Created ${nodeCount} nodes in ${formatTime(nodeTime)}`);
console.log(` Throughput: ${formatOps(nodeCount, nodeTime)}\n`);
results.push({ name: 'Node Creation', count: nodeCount, time: nodeTime });
// Benchmark 2: Batch Node Creation
console.log('📌 Benchmark 2: Batch Node Creation');
const batchSize = 1000;
const batchNodes = [];
for (let i = 0; i < batchSize; i++) {
batchNodes.push({
id: `batch_node_${i}`,
embedding: randomEmbedding(DIMENSIONS),
labels: ['BatchNode']
});
}
const batchNodeStart = performance.now();
await db.batchInsert({ nodes: batchNodes, edges: [] });
const batchNodeEnd = performance.now();
const batchNodeTime = batchNodeEnd - batchNodeStart;
console.log(` Inserted ${batchSize} nodes in ${formatTime(batchNodeTime)}`);
console.log(` Throughput: ${formatOps(batchSize, batchNodeTime)}\n`);
results.push({ name: 'Batch Node Creation', count: batchSize, time: batchNodeTime });
// Benchmark 3: Edge Creation
console.log('📌 Benchmark 3: Edge Creation');
const edgeCount = 1000;
const edgeStart = performance.now();
for (let i = 0; i < edgeCount; i++) {
const from = `node_${i % nodeCount}`;
const to = `node_${(i + 1) % nodeCount}`;
await db.createEdge({
from,
to,
description: 'CONNECTED_TO',
embedding: randomEmbedding(DIMENSIONS),
confidence: Math.random()
});
}
const edgeEnd = performance.now();
const edgeTime = edgeEnd - edgeStart;
console.log(` Created ${edgeCount} edges in ${formatTime(edgeTime)}`);
console.log(` Throughput: ${formatOps(edgeCount, edgeTime)}\n`);
results.push({ name: 'Edge Creation', count: edgeCount, time: edgeTime });
// Benchmark 4: Hyperedge Creation
console.log('📌 Benchmark 4: Hyperedge Creation');
const hyperedgeCount = 500;
const hyperedgeStart = performance.now();
for (let i = 0; i < hyperedgeCount; i++) {
const nodes = [];
const numNodes = 3 + Math.floor(Math.random() * 5); // 3-7 nodes per hyperedge
for (let j = 0; j < numNodes; j++) {
nodes.push(`node_${(i + j) % nodeCount}`);
}
await db.createHyperedge({
nodes,
description: `RELATIONSHIP_${i}`,
embedding: randomEmbedding(DIMENSIONS),
confidence: Math.random()
});
}
const hyperedgeEnd = performance.now();
const hyperedgeTime = hyperedgeEnd - hyperedgeStart;
console.log(` Created ${hyperedgeCount} hyperedges in ${formatTime(hyperedgeTime)}`);
console.log(` Throughput: ${formatOps(hyperedgeCount, hyperedgeTime)}\n`);
results.push({ name: 'Hyperedge Creation', count: hyperedgeCount, time: hyperedgeTime });
// Benchmark 5: Vector Similarity Search
console.log('📌 Benchmark 5: Vector Similarity Search');
const searchCount = 100;
const searchStart = performance.now();
for (let i = 0; i < searchCount; i++) {
await db.searchHyperedges({
embedding: randomEmbedding(DIMENSIONS),
k: SEARCH_K
});
}
const searchEnd = performance.now();
const searchTime = searchEnd - searchStart;
console.log(` Performed ${searchCount} searches (k=${SEARCH_K}) in ${formatTime(searchTime)}`);
console.log(` Throughput: ${formatOps(searchCount, searchTime)}\n`);
results.push({ name: 'Vector Search', count: searchCount, time: searchTime });
// Benchmark 6: k-hop Neighbor Traversal
console.log('📌 Benchmark 6: k-hop Neighbor Traversal');
const traversalCount = 100;
const traversalStart = performance.now();
for (let i = 0; i < traversalCount; i++) {
await db.kHopNeighbors(`node_${i % nodeCount}`, 2);
}
const traversalEnd = performance.now();
const traversalTime = traversalEnd - traversalStart;
console.log(` Performed ${traversalCount} 2-hop traversals in ${formatTime(traversalTime)}`);
console.log(` Throughput: ${formatOps(traversalCount, traversalTime)}\n`);
results.push({ name: 'k-hop Traversal', count: traversalCount, time: traversalTime });
// Benchmark 7: Statistics Query
console.log('📌 Benchmark 7: Statistics Query');
const statsCount = 1000;
const statsStart = performance.now();
for (let i = 0; i < statsCount; i++) {
await db.stats();
}
const statsEnd = performance.now();
const statsTime = statsEnd - statsStart;
console.log(` Performed ${statsCount} stats queries in ${formatTime(statsTime)}`);
console.log(` Throughput: ${formatOps(statsCount, statsTime)}\n`);
results.push({ name: 'Stats Query', count: statsCount, time: statsTime });
// Benchmark 8: Transaction Overhead
console.log('📌 Benchmark 8: Transaction Overhead');
const txCount = 100;
const txStart = performance.now();
for (let i = 0; i < txCount; i++) {
const txId = await db.begin();
await db.commit(txId);
}
const txEnd = performance.now();
const txTime = txEnd - txStart;
console.log(` Performed ${txCount} transactions in ${formatTime(txTime)}`);
console.log(` Throughput: ${formatOps(txCount, txTime)}\n`);
results.push({ name: 'Transaction', count: txCount, time: txTime });
// Summary
console.log('╔════════════════════════════════════════════════════════════════╗');
console.log('║ BENCHMARK SUMMARY ║');
console.log('╠════════════════════════════════════════════════════════════════╣');
for (const r of results) {
const ops = formatOps(r.count, r.time);
console.log(`${r.name.padEnd(25)} ${ops.padStart(20)} ${formatTime(r.time).padStart(12)}`);
}
console.log('╚════════════════════════════════════════════════════════════════╝');
// Final stats
const finalStats = await db.stats();
console.log(`\n📊 Final Database State:`);
console.log(` Total Nodes: ${finalStats.totalNodes.toLocaleString()}`);
console.log(` Total Edges: ${finalStats.totalEdges.toLocaleString()}`);
console.log(` Avg Degree: ${finalStats.avgDegree.toFixed(4)}`);
}
benchmark().catch(console.error);