-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbenchmark.js
More file actions
134 lines (118 loc) · 3.98 KB
/
Copy pathbenchmark.js
File metadata and controls
134 lines (118 loc) · 3.98 KB
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
const { initCacheSystem, query } = require('./rust-scriba.node');
const redis = require('redis');
const { performance } = require('perf_hooks');
async function runBenchmark(options) {
const ITERATIONS = options?.config?.iterations ?? 5000;
const CONCURRENT = options?.config?.concurrent ?? 100;
const LARGE_VALUE = 'x'.repeat(1024 * (options?.config?.largeValueInKb ?? 100));
initCacheSystem();
const redisClient = options?.url ? redis.createClient({ url }) : redis.createClient();
await redisClient.connect();
const key = 'test_key';
const smallValue = JSON.stringify({ msg: 'hello world', ts: Date.now() });
async function measure(fn) {
const start = performance.now();
await fn();
return performance.now() - start;
}
async function latencyPercentiles(getFn) {
const latencies = [];
for (let i = 0; i < ITERATIONS; i++) {
const start = performance.now();
await getFn();
latencies.push(performance.now() - start);
}
latencies.sort((a, b) => a - b);
return {
p50: latencies[Math.floor(ITERATIONS * 0.5)],
p95: latencies[Math.floor(ITERATIONS * 0.95)],
p99: latencies[Math.floor(ITERATIONS * 0.99)],
};
}
async function mixedOperations(getFn, setFn) {
return await measure(async () => {
const tasks = [];
for (let i = 0; i < ITERATIONS; i++) {
if (Math.random() < 0.7) tasks.push(getFn());
else tasks.push(setFn());
}
await Promise.all(tasks);
});
}
const results = {};
results.latency = {
redisSet: await measure(async () => {
for (let i = 0; i < ITERATIONS; i++) await redisClient.set(key, smallValue);
}),
redisGet: await measure(async () => {
for (let i = 0; i < ITERATIONS; i++) await redisClient.get(key);
}),
rustSet: await measure(async () => {
for (let i = 0; i < ITERATIONS; i++)
await query('_benchmark', `SET ${key} ${smallValue}`, 10000);
}),
rustGet: await measure(async () => {
for (let i = 0; i < ITERATIONS; i++)
await query('_benchmark', `GET ${key}`, 10000);
})
};
results.concurrent = {
redisSet: await measure(async () => {
const tasks = Array.from({ length: CONCURRENT }, () =>
redisClient.set(key, smallValue)
);
await Promise.all(tasks);
}),
redisGet: await measure(async () => {
const tasks = Array.from({ length: CONCURRENT }, () =>
redisClient.get(key)
);
await Promise.all(tasks);
}),
rustSet: await measure(async () => {
const tasks = Array.from({ length: CONCURRENT }, () =>
query('_benchmark', `SET ${key} ${smallValue}`, 10000)
);
await Promise.all(tasks);
}),
rustGet: await measure(async () => {
const tasks = Array.from({ length: CONCURRENT }, () =>
query('_benchmark', `GET ${key}`, 10000)
);
await Promise.all(tasks);
})
};
results.percentiles = {
redis: await latencyPercentiles(() => redisClient.get(key)),
rust: await latencyPercentiles(() => query('_benchmark', `GET ${key}`, 10000)),
};
results.mix = {
redis: await mixedOperations(
() => redisClient.get(key),
() => redisClient.set(key, smallValue)
),
rust: await mixedOperations(
() => query('_benchmark', `GET ${key}`, 10000),
() => query('_benchmark', `SET ${key} ${smallValue}`, 10000)
)
};
results.largeValues = {
redisSet: await measure(async () => {
for (let i = 0; i < 500; i++) await redisClient.set(key, LARGE_VALUE);
}),
redisGet: await measure(async () => {
for (let i = 0; i < 500; i++) await redisClient.get(key);
}),
rustSet: await measure(async () => {
for (let i = 0; i < 500; i++)
await query('_benchmark', `SET ${key} ${LARGE_VALUE}`, 10000);
}),
rustGet: await measure(async () => {
for (let i = 0; i < 500; i++)
await query('_benchmark', `GET ${key}`, 10000);
})
};
await redisClient.quit();
return results;
}
module.exports = { runBenchmark };