File size: 6,572 Bytes
529090e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
import { neo4jService } from '../database/Neo4jService';
import { graphMemoryService } from '../memory/GraphMemoryService';

interface BenchmarkResult {
    operation: string;
    iterations: number;
    totalTime: number;
    avgTime: number;
    minTime: number;
    maxTime: number;
    opsPerSecond: number;
}

async function benchmark(
    name: string,
    operation: () => Promise<void>,
    iterations: number = 100
): Promise<BenchmarkResult> {
    const times: number[] = [];

    for (let i = 0; i < iterations; i++) {
        const start = performance.now();
        await operation();
        const end = performance.now();
        times.push(end - start);
    }

    const totalTime = times.reduce((sum, t) => sum + t, 0);
    const avgTime = totalTime / iterations;
    const minTime = Math.min(...times);
    const maxTime = Math.max(...times);
    const opsPerSecond = 1000 / avgTime;

    return {
        operation: name,
        iterations,
        totalTime,
        avgTime,
        minTime,
        maxTime,
        opsPerSecond,
    };
}

async function runPerformanceBenchmarks() {
    console.log('πŸš€ Running Performance Benchmarks...\n');

    await neo4jService.connect();

    const results: BenchmarkResult[] = [];

    // Benchmark 1: Create Entity
    console.log('πŸ“Š Benchmarking: Create Entity...');
    const createResult = await benchmark(
        'Create Entity',
        async () => {
            await graphMemoryService.createEntity('BenchmarkEntity', 'Test', { data: 'test' });
        },
        50
    );
    results.push(createResult);
    console.log(`   Avg: ${createResult.avgTime.toFixed(2)}ms | Ops/sec: ${createResult.opsPerSecond.toFixed(0)}`);

    // Create test data for other benchmarks
    const entities = [];
    for (let i = 0; i < 100; i++) {
        const entity = await graphMemoryService.createEntity(
            'BenchmarkEntity',
            `Entity ${i}`,
            { index: i }
        );
        entities.push(entity);
    }

    // Benchmark 2: Search Entities
    console.log('πŸ“Š Benchmarking: Search Entities...');
    const searchResult = await benchmark(
        'Search Entities',
        async () => {
            await graphMemoryService.searchEntities('Entity');
        },
        100
    );
    results.push(searchResult);
    console.log(`   Avg: ${searchResult.avgTime.toFixed(2)}ms | Ops/sec: ${searchResult.opsPerSecond.toFixed(0)}`);

    // Benchmark 3: Get Entity by ID
    console.log('πŸ“Š Benchmarking: Get Entity by ID...');
    const getResult = await benchmark(
        'Get Entity by ID',
        async () => {
            const randomEntity = entities[Math.floor(Math.random() * entities.length)];
            await neo4jService.getNodeById(randomEntity.id);
        },
        100
    );
    results.push(getResult);
    console.log(`   Avg: ${getResult.avgTime.toFixed(2)}ms | Ops/sec: ${getResult.opsPerSecond.toFixed(0)}`);

    // Benchmark 4: Create Relation
    console.log('πŸ“Š Benchmarking: Create Relation...');
    const relationResult = await benchmark(
        'Create Relation',
        async () => {
            const source = entities[Math.floor(Math.random() * entities.length)];
            const target = entities[Math.floor(Math.random() * entities.length)];
            if (source.id !== target.id) {
                await graphMemoryService.createRelation(source.id, target.id, 'BENCHMARK_REL');
            }
        },
        50
    );
    results.push(relationResult);
    console.log(`   Avg: ${relationResult.avgTime.toFixed(2)}ms | Ops/sec: ${relationResult.opsPerSecond.toFixed(0)}`);

    // Benchmark 5: Get Related Entities
    console.log('πŸ“Š Benchmarking: Get Related Entities...');
    const relatedResult = await benchmark(
        'Get Related Entities',
        async () => {
            const randomEntity = entities[Math.floor(Math.random() * entities.length)];
            await graphMemoryService.getRelatedEntities(randomEntity.id);
        },
        100
    );
    results.push(relatedResult);
    console.log(`   Avg: ${relatedResult.avgTime.toFixed(2)}ms | Ops/sec: ${relatedResult.opsPerSecond.toFixed(0)}`);

    // Benchmark 6: Graph Statistics
    console.log('πŸ“Š Benchmarking: Graph Statistics...');
    const statsResult = await benchmark(
        'Graph Statistics',
        async () => {
            await graphMemoryService.getStatistics();
        },
        20
    );
    results.push(statsResult);
    console.log(`   Avg: ${statsResult.avgTime.toFixed(2)}ms | Ops/sec: ${statsResult.opsPerSecond.toFixed(0)}`);

    // Cleanup
    console.log('\n🧹 Cleaning up test data...');
    await neo4jService.runQuery('MATCH (n:BenchmarkEntity) DETACH DELETE n');

    await neo4jService.disconnect();

    // Summary
    console.log('\nπŸ“Š Performance Benchmark Summary:');
    console.log('═'.repeat(80));
    console.log('Operation'.padEnd(30) + 'Avg Time'.padEnd(15) + 'Min/Max'.padEnd(20) + 'Ops/sec');
    console.log('─'.repeat(80));

    results.forEach(r => {
        console.log(
            r.operation.padEnd(30) +
            `${r.avgTime.toFixed(2)}ms`.padEnd(15) +
            `${r.minTime.toFixed(2)}/${r.maxTime.toFixed(2)}ms`.padEnd(20) +
            r.opsPerSecond.toFixed(0)
        );
    });

    console.log('═'.repeat(80));

    // Performance targets
    const targets = {
        'Create Entity': 100, // < 100ms
        'Search Entities': 50, // < 50ms
        'Get Entity by ID': 10, // < 10ms
        'Create Relation': 100, // < 100ms
        'Get Related Entities': 50, // < 50ms
        'Graph Statistics': 200, // < 200ms
    };

    console.log('\n🎯 Performance Target Analysis:');
    let allPassed = true;

    results.forEach(r => {
        const target = targets[r.operation as keyof typeof targets];
        const passed = r.avgTime < target;
        const status = passed ? 'βœ…' : '❌';
        allPassed = allPassed && passed;

        console.log(`${status} ${r.operation}: ${r.avgTime.toFixed(2)}ms (target: <${target}ms)`);
    });

    if (allPassed) {
        console.log('\nπŸŽ‰ All performance targets met!');
    } else {
        console.log('\n⚠️  Some performance targets not met. Consider optimization.');
    }

    return results;
}

// Run if executed directly
runPerformanceBenchmarks()
    .then(() => {
        console.log('\nβœ… Benchmarks completed');
        process.exit(0);
    })
    .catch(error => {
        console.error('\n❌ Benchmark failed:', error);
        process.exit(1);
    });

export { runPerformanceBenchmarks };