koa-classic-server 1.2.0 ā 2.0.0
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/BENCHMARKS.md +317 -0
- package/CREATE_RELEASE.sh +53 -0
- package/EXAMPLES_INDEX_OPTION.md +395 -0
- package/INDEX_OPTION_PRIORITY.md +527 -0
- package/OPTIMIZATION_HTTP_CACHING.md +687 -0
- package/PERFORMANCE_ANALYSIS.md +839 -0
- package/PERFORMANCE_COMPARISON.md +388 -0
- package/README.md +21 -5
- package/__tests__/index-option.test.js +447 -0
- package/__tests__/performance.test.js +301 -0
- package/benchmark-results-baseline-v1.2.0.txt +354 -0
- package/benchmark-results-optimized-v2.0.0.txt +354 -0
- package/benchmark.js +239 -0
- package/demo-regex-index.js +140 -0
- package/index.cjs +201 -51
- package/jest.config.js +18 -0
- package/package.json +9 -4
- package/publish-to-npm.sh +65 -0
- package/scripts/setup-benchmark.js +178 -0
- package/test-regex-quick.js +158 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance Benchmark Tests
|
|
3
|
+
*
|
|
4
|
+
* These tests measure current performance to establish a baseline.
|
|
5
|
+
* After optimizations, run these tests again to measure improvements.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* npm run test:performance
|
|
9
|
+
*
|
|
10
|
+
* To save results:
|
|
11
|
+
* npm run test:performance > benchmark-results-v1.2.0.txt
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const Koa = require('koa');
|
|
15
|
+
const supertest = require('supertest');
|
|
16
|
+
const koaClassicServer = require('../index.cjs');
|
|
17
|
+
const path = require('path');
|
|
18
|
+
const fs = require('fs');
|
|
19
|
+
|
|
20
|
+
const BENCHMARK_DIR = path.join(__dirname, '../benchmark-data');
|
|
21
|
+
|
|
22
|
+
// Check if benchmark data exists
|
|
23
|
+
if (!fs.existsSync(BENCHMARK_DIR)) {
|
|
24
|
+
console.error('\nā Benchmark data not found!');
|
|
25
|
+
console.error('Please run: node scripts/setup-benchmark.js\n');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Helper to measure execution time
|
|
30
|
+
function measureTime(fn) {
|
|
31
|
+
const start = process.hrtime.bigint();
|
|
32
|
+
const result = fn();
|
|
33
|
+
const end = process.hrtime.bigint();
|
|
34
|
+
const durationMs = Number(end - start) / 1000000; // Convert to ms
|
|
35
|
+
return { result, durationMs };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function measureTimeAsync(fn) {
|
|
39
|
+
const start = process.hrtime.bigint();
|
|
40
|
+
const result = await fn();
|
|
41
|
+
const end = process.hrtime.bigint();
|
|
42
|
+
const durationMs = Number(end - start) / 1000000;
|
|
43
|
+
return { result, durationMs };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Helper to run multiple iterations and get statistics
|
|
47
|
+
async function benchmark(name, fn, iterations = 10) {
|
|
48
|
+
const times = [];
|
|
49
|
+
|
|
50
|
+
for (let i = 0; i < iterations; i++) {
|
|
51
|
+
const { durationMs } = await measureTimeAsync(fn);
|
|
52
|
+
times.push(durationMs);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const avg = times.reduce((a, b) => a + b, 0) / times.length;
|
|
56
|
+
const min = Math.min(...times);
|
|
57
|
+
const max = Math.max(...times);
|
|
58
|
+
const median = times.sort((a, b) => a - b)[Math.floor(times.length / 2)];
|
|
59
|
+
|
|
60
|
+
return { name, avg, min, max, median, times };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
describe('Performance Benchmarks - BASELINE (v1.2.0)', () => {
|
|
64
|
+
let app;
|
|
65
|
+
let server;
|
|
66
|
+
let request;
|
|
67
|
+
|
|
68
|
+
beforeAll(() => {
|
|
69
|
+
app = new Koa();
|
|
70
|
+
app.use(koaClassicServer(BENCHMARK_DIR));
|
|
71
|
+
server = app.listen();
|
|
72
|
+
request = supertest(server);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
afterAll(() => {
|
|
76
|
+
server.close();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('File Serving Performance', () => {
|
|
80
|
+
test('Benchmark: Small file (1KB) - 100 iterations', async () => {
|
|
81
|
+
const stats = await benchmark(
|
|
82
|
+
'Small file (1KB)',
|
|
83
|
+
async () => {
|
|
84
|
+
const res = await request.get('/small-files/file-1.txt');
|
|
85
|
+
expect(res.status).toBe(200);
|
|
86
|
+
},
|
|
87
|
+
100
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
console.log('\nš Small File (1KB) Benchmark:');
|
|
91
|
+
console.log(` Average: ${stats.avg.toFixed(2)}ms`);
|
|
92
|
+
console.log(` Median: ${stats.median.toFixed(2)}ms`);
|
|
93
|
+
console.log(` Min: ${stats.min.toFixed(2)}ms`);
|
|
94
|
+
console.log(` Max: ${stats.max.toFixed(2)}ms`);
|
|
95
|
+
|
|
96
|
+
expect(stats.avg).toBeLessThan(50); // Should be fast
|
|
97
|
+
}, 30000);
|
|
98
|
+
|
|
99
|
+
test('Benchmark: Medium file (100KB) - 50 iterations', async () => {
|
|
100
|
+
const stats = await benchmark(
|
|
101
|
+
'Medium file (100KB)',
|
|
102
|
+
async () => {
|
|
103
|
+
const res = await request.get('/medium-files/file-1.txt');
|
|
104
|
+
expect(res.status).toBe(200);
|
|
105
|
+
},
|
|
106
|
+
50
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
console.log('\nš Medium File (100KB) Benchmark:');
|
|
110
|
+
console.log(` Average: ${stats.avg.toFixed(2)}ms`);
|
|
111
|
+
console.log(` Median: ${stats.median.toFixed(2)}ms`);
|
|
112
|
+
console.log(` Min: ${stats.min.toFixed(2)}ms`);
|
|
113
|
+
console.log(` Max: ${stats.max.toFixed(2)}ms`);
|
|
114
|
+
|
|
115
|
+
expect(stats.avg).toBeLessThan(100);
|
|
116
|
+
}, 30000);
|
|
117
|
+
|
|
118
|
+
test('Benchmark: Large file (1MB) - 20 iterations', async () => {
|
|
119
|
+
const stats = await benchmark(
|
|
120
|
+
'Large file (1MB)',
|
|
121
|
+
async () => {
|
|
122
|
+
const res = await request.get('/large-files/file-1.txt');
|
|
123
|
+
expect(res.status).toBe(200);
|
|
124
|
+
},
|
|
125
|
+
20
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
console.log('\nš Large File (1MB) Benchmark:');
|
|
129
|
+
console.log(` Average: ${stats.avg.toFixed(2)}ms`);
|
|
130
|
+
console.log(` Median: ${stats.median.toFixed(2)}ms`);
|
|
131
|
+
console.log(` Min: ${stats.min.toFixed(2)}ms`);
|
|
132
|
+
console.log(` Max: ${stats.max.toFixed(2)}ms`);
|
|
133
|
+
|
|
134
|
+
expect(stats.avg).toBeLessThan(500);
|
|
135
|
+
}, 30000);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
describe('Directory Listing Performance', () => {
|
|
139
|
+
test('Benchmark: Small directory (100 files) - 50 iterations', async () => {
|
|
140
|
+
const stats = await benchmark(
|
|
141
|
+
'Directory listing (100 files)',
|
|
142
|
+
async () => {
|
|
143
|
+
const res = await request.get('/small-files/');
|
|
144
|
+
expect(res.status).toBe(200);
|
|
145
|
+
expect(res.text).toContain('file-1.txt');
|
|
146
|
+
},
|
|
147
|
+
50
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
console.log('\nš Small Directory (100 files) Benchmark:');
|
|
151
|
+
console.log(` Average: ${stats.avg.toFixed(2)}ms`);
|
|
152
|
+
console.log(` Median: ${stats.median.toFixed(2)}ms`);
|
|
153
|
+
console.log(` Min: ${stats.min.toFixed(2)}ms`);
|
|
154
|
+
console.log(` Max: ${stats.max.toFixed(2)}ms`);
|
|
155
|
+
}, 30000);
|
|
156
|
+
|
|
157
|
+
test('Benchmark: Large directory (1,000 files) - 20 iterations', async () => {
|
|
158
|
+
const stats = await benchmark(
|
|
159
|
+
'Directory listing (1,000 files)',
|
|
160
|
+
async () => {
|
|
161
|
+
const res = await request.get('/large-directory/');
|
|
162
|
+
expect(res.status).toBe(200);
|
|
163
|
+
expect(res.text).toContain('item-0001.txt');
|
|
164
|
+
},
|
|
165
|
+
20
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
console.log('\nš Large Directory (1,000 files) Benchmark:');
|
|
169
|
+
console.log(` Average: ${stats.avg.toFixed(2)}ms`);
|
|
170
|
+
console.log(` Median: ${stats.median.toFixed(2)}ms`);
|
|
171
|
+
console.log(` Min: ${stats.min.toFixed(2)}ms`);
|
|
172
|
+
console.log(` Max: ${stats.max.toFixed(2)}ms`);
|
|
173
|
+
|
|
174
|
+
// This is expected to be slow with current sync implementation
|
|
175
|
+
console.log(` ā ļø WARNING: This will be MUCH faster after async optimization`);
|
|
176
|
+
}, 60000);
|
|
177
|
+
|
|
178
|
+
test('Benchmark: Very large directory (10,000 files) - 5 iterations', async () => {
|
|
179
|
+
const stats = await benchmark(
|
|
180
|
+
'Directory listing (10,000 files)',
|
|
181
|
+
async () => {
|
|
182
|
+
const res = await request.get('/very-large-directory/');
|
|
183
|
+
expect(res.status).toBe(200);
|
|
184
|
+
expect(res.text).toContain('item-00001.txt');
|
|
185
|
+
},
|
|
186
|
+
5
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
console.log('\nš Very Large Directory (10,000 files) Benchmark:');
|
|
190
|
+
console.log(` Average: ${stats.avg.toFixed(2)}ms`);
|
|
191
|
+
console.log(` Median: ${stats.median.toFixed(2)}ms`);
|
|
192
|
+
console.log(` Min: ${stats.min.toFixed(2)}ms`);
|
|
193
|
+
console.log(` Max: ${stats.max.toFixed(2)}ms`);
|
|
194
|
+
console.log(` ā ļø WARNING: Event loop BLOCKED during this operation!`);
|
|
195
|
+
console.log(` ā ļø Expected to drop to ~${(stats.avg * 0.3).toFixed(2)}ms after optimization`);
|
|
196
|
+
}, 120000);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
describe('Concurrent Request Performance', () => {
|
|
200
|
+
test('Benchmark: 10 concurrent small file requests', async () => {
|
|
201
|
+
const start = process.hrtime.bigint();
|
|
202
|
+
|
|
203
|
+
const promises = Array.from({ length: 10 }, (_, i) =>
|
|
204
|
+
request.get(`/small-files/file-${i + 1}.txt`)
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
const results = await Promise.all(promises);
|
|
208
|
+
|
|
209
|
+
const end = process.hrtime.bigint();
|
|
210
|
+
const totalTime = Number(end - start) / 1000000;
|
|
211
|
+
|
|
212
|
+
console.log('\nš 10 Concurrent Small Files:');
|
|
213
|
+
console.log(` Total time: ${totalTime.toFixed(2)}ms`);
|
|
214
|
+
console.log(` Avg per request: ${(totalTime / 10).toFixed(2)}ms`);
|
|
215
|
+
|
|
216
|
+
results.forEach(res => expect(res.status).toBe(200));
|
|
217
|
+
}, 10000);
|
|
218
|
+
|
|
219
|
+
test('Benchmark: 5 concurrent directory listings (100 files each)', async () => {
|
|
220
|
+
const start = process.hrtime.bigint();
|
|
221
|
+
|
|
222
|
+
const promises = Array.from({ length: 5 }, () =>
|
|
223
|
+
request.get('/small-files/')
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
const results = await Promise.all(promises);
|
|
227
|
+
|
|
228
|
+
const end = process.hrtime.bigint();
|
|
229
|
+
const totalTime = Number(end - start) / 1000000;
|
|
230
|
+
|
|
231
|
+
console.log('\nš 5 Concurrent Directory Listings (100 files):');
|
|
232
|
+
console.log(` Total time: ${totalTime.toFixed(2)}ms`);
|
|
233
|
+
console.log(` Avg per request: ${(totalTime / 5).toFixed(2)}ms`);
|
|
234
|
+
console.log(` ā ļø With current sync code, these run SEQUENTIALLY`);
|
|
235
|
+
console.log(` ā ļø After async optimization, will run in PARALLEL`);
|
|
236
|
+
|
|
237
|
+
results.forEach(res => expect(res.status).toBe(200));
|
|
238
|
+
}, 30000);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
describe('404 Not Found Performance', () => {
|
|
242
|
+
test('Benchmark: Non-existent file - 50 iterations', async () => {
|
|
243
|
+
const stats = await benchmark(
|
|
244
|
+
'404 Not Found',
|
|
245
|
+
async () => {
|
|
246
|
+
const res = await request.get('/does-not-exist-12345.txt');
|
|
247
|
+
expect(res.status).toBe(404);
|
|
248
|
+
},
|
|
249
|
+
50
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
console.log('\nš 404 Not Found Benchmark:');
|
|
253
|
+
console.log(` Average: ${stats.avg.toFixed(2)}ms`);
|
|
254
|
+
console.log(` Median: ${stats.median.toFixed(2)}ms`);
|
|
255
|
+
console.log(` Min: ${stats.min.toFixed(2)}ms`);
|
|
256
|
+
console.log(` Max: ${stats.max.toFixed(2)}ms`);
|
|
257
|
+
}, 10000);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
describe('Memory Usage (Informational)', () => {
|
|
261
|
+
test('Memory usage during large directory listing', async () => {
|
|
262
|
+
// Force garbage collection if available
|
|
263
|
+
if (global.gc) {
|
|
264
|
+
global.gc();
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const memBefore = process.memoryUsage();
|
|
268
|
+
|
|
269
|
+
// Request large directory
|
|
270
|
+
const res = await request.get('/very-large-directory/');
|
|
271
|
+
expect(res.status).toBe(200);
|
|
272
|
+
|
|
273
|
+
const memAfter = process.memoryUsage();
|
|
274
|
+
|
|
275
|
+
const heapUsedDiff = (memAfter.heapUsed - memBefore.heapUsed) / 1024 / 1024;
|
|
276
|
+
const externalDiff = (memAfter.external - memBefore.external) / 1024 / 1024;
|
|
277
|
+
|
|
278
|
+
console.log('\nš Memory Usage (10,000 files directory):');
|
|
279
|
+
console.log(` Heap used increase: ${heapUsedDiff.toFixed(2)} MB`);
|
|
280
|
+
console.log(` External increase: ${externalDiff.toFixed(2)} MB`);
|
|
281
|
+
console.log(` Response size: ${(res.text.length / 1024 / 1024).toFixed(2)} MB`);
|
|
282
|
+
console.log(` ā ļø Expected to reduce by ~30-40% after optimization`);
|
|
283
|
+
}, 30000);
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
// Summary report
|
|
288
|
+
afterAll(() => {
|
|
289
|
+
console.log('\n' + '='.repeat(70));
|
|
290
|
+
console.log('š BASELINE BENCHMARK SUMMARY');
|
|
291
|
+
console.log('='.repeat(70));
|
|
292
|
+
console.log('\nThese results represent the CURRENT performance (v1.2.0)');
|
|
293
|
+
console.log('After implementing optimizations, run this test again to see improvements.\n');
|
|
294
|
+
console.log('Expected improvements after optimization:');
|
|
295
|
+
console.log(' ā Small files: 10-20% faster (async operations)');
|
|
296
|
+
console.log(' ā Large directories: 50-70% faster (async + array join)');
|
|
297
|
+
console.log(' ā Concurrent requests: 5-10x faster (non-blocking event loop)');
|
|
298
|
+
console.log(' ā Memory usage: 30-40% reduction (array join vs concatenation)');
|
|
299
|
+
console.log(' ā With HTTP caching: 80-95% faster (304 responses)');
|
|
300
|
+
console.log('='.repeat(70) + '\n');
|
|
301
|
+
});
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
|
|
2
|
+
> koa-classic-server@1.2.0 test:performance
|
|
3
|
+
> jest __tests__/performance.test.js --runInBand
|
|
4
|
+
|
|
5
|
+
console.log
|
|
6
|
+
|
|
7
|
+
š Small File (1KB) Benchmark:
|
|
8
|
+
|
|
9
|
+
at Object.log (__tests__/performance.test.js:90:21)
|
|
10
|
+
|
|
11
|
+
console.log
|
|
12
|
+
Average: 2.93ms
|
|
13
|
+
|
|
14
|
+
at Object.log (__tests__/performance.test.js:91:21)
|
|
15
|
+
|
|
16
|
+
console.log
|
|
17
|
+
Median: 2.54ms
|
|
18
|
+
|
|
19
|
+
at Object.log (__tests__/performance.test.js:92:21)
|
|
20
|
+
|
|
21
|
+
console.log
|
|
22
|
+
Min: 1.99ms
|
|
23
|
+
|
|
24
|
+
at Object.log (__tests__/performance.test.js:93:21)
|
|
25
|
+
|
|
26
|
+
console.log
|
|
27
|
+
Max: 26.87ms
|
|
28
|
+
|
|
29
|
+
at Object.log (__tests__/performance.test.js:94:21)
|
|
30
|
+
|
|
31
|
+
console.log
|
|
32
|
+
|
|
33
|
+
š Medium File (100KB) Benchmark:
|
|
34
|
+
|
|
35
|
+
at Object.log (__tests__/performance.test.js:109:21)
|
|
36
|
+
|
|
37
|
+
console.log
|
|
38
|
+
Average: 3.59ms
|
|
39
|
+
|
|
40
|
+
at Object.log (__tests__/performance.test.js:110:21)
|
|
41
|
+
|
|
42
|
+
console.log
|
|
43
|
+
Median: 3.51ms
|
|
44
|
+
|
|
45
|
+
at Object.log (__tests__/performance.test.js:111:21)
|
|
46
|
+
|
|
47
|
+
console.log
|
|
48
|
+
Min: 2.46ms
|
|
49
|
+
|
|
50
|
+
at Object.log (__tests__/performance.test.js:112:21)
|
|
51
|
+
|
|
52
|
+
console.log
|
|
53
|
+
Max: 8.36ms
|
|
54
|
+
|
|
55
|
+
at Object.log (__tests__/performance.test.js:113:21)
|
|
56
|
+
|
|
57
|
+
console.log
|
|
58
|
+
|
|
59
|
+
š Large File (1MB) Benchmark:
|
|
60
|
+
|
|
61
|
+
at Object.log (__tests__/performance.test.js:128:21)
|
|
62
|
+
|
|
63
|
+
console.log
|
|
64
|
+
Average: 9.03ms
|
|
65
|
+
|
|
66
|
+
at Object.log (__tests__/performance.test.js:129:21)
|
|
67
|
+
|
|
68
|
+
console.log
|
|
69
|
+
Median: 8.35ms
|
|
70
|
+
|
|
71
|
+
at Object.log (__tests__/performance.test.js:130:21)
|
|
72
|
+
|
|
73
|
+
console.log
|
|
74
|
+
Min: 5.46ms
|
|
75
|
+
|
|
76
|
+
at Object.log (__tests__/performance.test.js:131:21)
|
|
77
|
+
|
|
78
|
+
console.log
|
|
79
|
+
Max: 13.81ms
|
|
80
|
+
|
|
81
|
+
at Object.log (__tests__/performance.test.js:132:21)
|
|
82
|
+
|
|
83
|
+
console.log
|
|
84
|
+
|
|
85
|
+
š Small Directory (100 files) Benchmark:
|
|
86
|
+
|
|
87
|
+
at Object.log (__tests__/performance.test.js:150:21)
|
|
88
|
+
|
|
89
|
+
console.log
|
|
90
|
+
Average: 2.65ms
|
|
91
|
+
|
|
92
|
+
at Object.log (__tests__/performance.test.js:151:21)
|
|
93
|
+
|
|
94
|
+
console.log
|
|
95
|
+
Median: 2.54ms
|
|
96
|
+
|
|
97
|
+
at Object.log (__tests__/performance.test.js:152:21)
|
|
98
|
+
|
|
99
|
+
console.log
|
|
100
|
+
Min: 2.22ms
|
|
101
|
+
|
|
102
|
+
at Object.log (__tests__/performance.test.js:153:21)
|
|
103
|
+
|
|
104
|
+
console.log
|
|
105
|
+
Max: 4.69ms
|
|
106
|
+
|
|
107
|
+
at Object.log (__tests__/performance.test.js:154:21)
|
|
108
|
+
|
|
109
|
+
console.log
|
|
110
|
+
|
|
111
|
+
š Large Directory (1,000 files) Benchmark:
|
|
112
|
+
|
|
113
|
+
at Object.log (__tests__/performance.test.js:168:21)
|
|
114
|
+
|
|
115
|
+
console.log
|
|
116
|
+
Average: 9.23ms
|
|
117
|
+
|
|
118
|
+
at Object.log (__tests__/performance.test.js:169:21)
|
|
119
|
+
|
|
120
|
+
console.log
|
|
121
|
+
Median: 9.14ms
|
|
122
|
+
|
|
123
|
+
at Object.log (__tests__/performance.test.js:170:21)
|
|
124
|
+
|
|
125
|
+
console.log
|
|
126
|
+
Min: 8.26ms
|
|
127
|
+
|
|
128
|
+
at Object.log (__tests__/performance.test.js:171:21)
|
|
129
|
+
|
|
130
|
+
console.log
|
|
131
|
+
Max: 11.64ms
|
|
132
|
+
|
|
133
|
+
at Object.log (__tests__/performance.test.js:172:21)
|
|
134
|
+
|
|
135
|
+
console.log
|
|
136
|
+
ā ļø WARNING: This will be MUCH faster after async optimization
|
|
137
|
+
|
|
138
|
+
at Object.log (__tests__/performance.test.js:175:21)
|
|
139
|
+
|
|
140
|
+
console.log
|
|
141
|
+
|
|
142
|
+
š Very Large Directory (10,000 files) Benchmark:
|
|
143
|
+
|
|
144
|
+
at Object.log (__tests__/performance.test.js:189:21)
|
|
145
|
+
|
|
146
|
+
console.log
|
|
147
|
+
Average: 102.37ms
|
|
148
|
+
|
|
149
|
+
at Object.log (__tests__/performance.test.js:190:21)
|
|
150
|
+
|
|
151
|
+
console.log
|
|
152
|
+
Median: 95.13ms
|
|
153
|
+
|
|
154
|
+
at Object.log (__tests__/performance.test.js:191:21)
|
|
155
|
+
|
|
156
|
+
console.log
|
|
157
|
+
Min: 90.91ms
|
|
158
|
+
|
|
159
|
+
at Object.log (__tests__/performance.test.js:192:21)
|
|
160
|
+
|
|
161
|
+
console.log
|
|
162
|
+
Max: 120.85ms
|
|
163
|
+
|
|
164
|
+
at Object.log (__tests__/performance.test.js:193:21)
|
|
165
|
+
|
|
166
|
+
console.log
|
|
167
|
+
ā ļø WARNING: Event loop BLOCKED during this operation!
|
|
168
|
+
|
|
169
|
+
at Object.log (__tests__/performance.test.js:194:21)
|
|
170
|
+
|
|
171
|
+
console.log
|
|
172
|
+
ā ļø Expected to drop to ~30.71ms after optimization
|
|
173
|
+
|
|
174
|
+
at Object.log (__tests__/performance.test.js:195:21)
|
|
175
|
+
|
|
176
|
+
console.log
|
|
177
|
+
|
|
178
|
+
š 10 Concurrent Small Files:
|
|
179
|
+
|
|
180
|
+
at Object.log (__tests__/performance.test.js:212:21)
|
|
181
|
+
|
|
182
|
+
console.log
|
|
183
|
+
Total time: 15.50ms
|
|
184
|
+
|
|
185
|
+
at Object.log (__tests__/performance.test.js:213:21)
|
|
186
|
+
|
|
187
|
+
console.log
|
|
188
|
+
Avg per request: 1.55ms
|
|
189
|
+
|
|
190
|
+
at Object.log (__tests__/performance.test.js:214:21)
|
|
191
|
+
|
|
192
|
+
console.log
|
|
193
|
+
|
|
194
|
+
š 5 Concurrent Directory Listings (100 files):
|
|
195
|
+
|
|
196
|
+
at Object.log (__tests__/performance.test.js:231:21)
|
|
197
|
+
|
|
198
|
+
console.log
|
|
199
|
+
Total time: 11.30ms
|
|
200
|
+
|
|
201
|
+
at Object.log (__tests__/performance.test.js:232:21)
|
|
202
|
+
|
|
203
|
+
console.log
|
|
204
|
+
Avg per request: 2.26ms
|
|
205
|
+
|
|
206
|
+
at Object.log (__tests__/performance.test.js:233:21)
|
|
207
|
+
|
|
208
|
+
console.log
|
|
209
|
+
ā ļø With current sync code, these run SEQUENTIALLY
|
|
210
|
+
|
|
211
|
+
at Object.log (__tests__/performance.test.js:234:21)
|
|
212
|
+
|
|
213
|
+
console.log
|
|
214
|
+
ā ļø After async optimization, will run in PARALLEL
|
|
215
|
+
|
|
216
|
+
at Object.log (__tests__/performance.test.js:235:21)
|
|
217
|
+
|
|
218
|
+
console.log
|
|
219
|
+
|
|
220
|
+
š 404 Not Found Benchmark:
|
|
221
|
+
|
|
222
|
+
at Object.log (__tests__/performance.test.js:252:21)
|
|
223
|
+
|
|
224
|
+
console.log
|
|
225
|
+
Average: 1.26ms
|
|
226
|
+
|
|
227
|
+
at Object.log (__tests__/performance.test.js:253:21)
|
|
228
|
+
|
|
229
|
+
console.log
|
|
230
|
+
Median: 1.24ms
|
|
231
|
+
|
|
232
|
+
at Object.log (__tests__/performance.test.js:254:21)
|
|
233
|
+
|
|
234
|
+
console.log
|
|
235
|
+
Min: 1.05ms
|
|
236
|
+
|
|
237
|
+
at Object.log (__tests__/performance.test.js:255:21)
|
|
238
|
+
|
|
239
|
+
console.log
|
|
240
|
+
Max: 2.17ms
|
|
241
|
+
|
|
242
|
+
at Object.log (__tests__/performance.test.js:256:21)
|
|
243
|
+
|
|
244
|
+
console.log
|
|
245
|
+
|
|
246
|
+
š Memory Usage (10,000 files directory):
|
|
247
|
+
|
|
248
|
+
at Object.log (__tests__/performance.test.js:278:21)
|
|
249
|
+
|
|
250
|
+
console.log
|
|
251
|
+
Heap used increase: 1.16 MB
|
|
252
|
+
|
|
253
|
+
at Object.log (__tests__/performance.test.js:279:21)
|
|
254
|
+
|
|
255
|
+
console.log
|
|
256
|
+
External increase: 2.57 MB
|
|
257
|
+
|
|
258
|
+
at Object.log (__tests__/performance.test.js:280:21)
|
|
259
|
+
|
|
260
|
+
console.log
|
|
261
|
+
Response size: 1.29 MB
|
|
262
|
+
|
|
263
|
+
at Object.log (__tests__/performance.test.js:281:21)
|
|
264
|
+
|
|
265
|
+
console.log
|
|
266
|
+
ā ļø Expected to reduce by ~30-40% after optimization
|
|
267
|
+
|
|
268
|
+
at Object.log (__tests__/performance.test.js:282:21)
|
|
269
|
+
|
|
270
|
+
console.log
|
|
271
|
+
|
|
272
|
+
======================================================================
|
|
273
|
+
|
|
274
|
+
at Object.log (__tests__/performance.test.js:289:13)
|
|
275
|
+
|
|
276
|
+
console.log
|
|
277
|
+
š BASELINE BENCHMARK SUMMARY
|
|
278
|
+
|
|
279
|
+
at Object.log (__tests__/performance.test.js:290:13)
|
|
280
|
+
|
|
281
|
+
console.log
|
|
282
|
+
======================================================================
|
|
283
|
+
|
|
284
|
+
at Object.log (__tests__/performance.test.js:291:13)
|
|
285
|
+
|
|
286
|
+
console.log
|
|
287
|
+
|
|
288
|
+
These results represent the CURRENT performance (v1.2.0)
|
|
289
|
+
|
|
290
|
+
at Object.log (__tests__/performance.test.js:292:13)
|
|
291
|
+
|
|
292
|
+
console.log
|
|
293
|
+
After implementing optimizations, run this test again to see improvements.
|
|
294
|
+
|
|
295
|
+
at Object.log (__tests__/performance.test.js:293:13)
|
|
296
|
+
|
|
297
|
+
console.log
|
|
298
|
+
Expected improvements after optimization:
|
|
299
|
+
|
|
300
|
+
at Object.log (__tests__/performance.test.js:294:13)
|
|
301
|
+
|
|
302
|
+
console.log
|
|
303
|
+
ā Small files: 10-20% faster (async operations)
|
|
304
|
+
|
|
305
|
+
at Object.log (__tests__/performance.test.js:295:13)
|
|
306
|
+
|
|
307
|
+
console.log
|
|
308
|
+
ā Large directories: 50-70% faster (async + array join)
|
|
309
|
+
|
|
310
|
+
at Object.log (__tests__/performance.test.js:296:13)
|
|
311
|
+
|
|
312
|
+
console.log
|
|
313
|
+
ā Concurrent requests: 5-10x faster (non-blocking event loop)
|
|
314
|
+
|
|
315
|
+
at Object.log (__tests__/performance.test.js:297:13)
|
|
316
|
+
|
|
317
|
+
console.log
|
|
318
|
+
ā Memory usage: 30-40% reduction (array join vs concatenation)
|
|
319
|
+
|
|
320
|
+
at Object.log (__tests__/performance.test.js:298:13)
|
|
321
|
+
|
|
322
|
+
console.log
|
|
323
|
+
ā With HTTP caching: 80-95% faster (304 responses)
|
|
324
|
+
|
|
325
|
+
at Object.log (__tests__/performance.test.js:299:13)
|
|
326
|
+
|
|
327
|
+
console.log
|
|
328
|
+
======================================================================
|
|
329
|
+
|
|
330
|
+
at Object.log (__tests__/performance.test.js:300:13)
|
|
331
|
+
|
|
332
|
+
PASS __tests__/performance.test.js
|
|
333
|
+
Performance Benchmarks - BASELINE (v1.2.0)
|
|
334
|
+
File Serving Performance
|
|
335
|
+
ā Benchmark: Small file (1KB) - 100 iterations (318 ms)
|
|
336
|
+
ā Benchmark: Medium file (100KB) - 50 iterations (184 ms)
|
|
337
|
+
ā Benchmark: Large file (1MB) - 20 iterations (183 ms)
|
|
338
|
+
Directory Listing Performance
|
|
339
|
+
ā Benchmark: Small directory (100 files) - 50 iterations (135 ms)
|
|
340
|
+
ā Benchmark: Large directory (1,000 files) - 20 iterations (188 ms)
|
|
341
|
+
ā Benchmark: Very large directory (10,000 files) - 5 iterations (515 ms)
|
|
342
|
+
Concurrent Request Performance
|
|
343
|
+
ā Benchmark: 10 concurrent small file requests (18 ms)
|
|
344
|
+
ā Benchmark: 5 concurrent directory listings (100 files each) (14 ms)
|
|
345
|
+
404 Not Found Performance
|
|
346
|
+
ā Benchmark: Non-existent file - 50 iterations (66 ms)
|
|
347
|
+
Memory Usage (Informational)
|
|
348
|
+
ā Memory usage during large directory listing (88 ms)
|
|
349
|
+
|
|
350
|
+
Test Suites: 1 passed, 1 total
|
|
351
|
+
Tests: 10 passed, 10 total
|
|
352
|
+
Snapshots: 0 total
|
|
353
|
+
Time: 3.227 s, estimated 4 s
|
|
354
|
+
Ran all test suites matching /__tests__\/performance.test.js/i.
|