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
| class WasmProfiler {
constructor(wasmModule) {
this.wasm = wasmModule;
this.metrics = new Map();
}
wrapFunction(functionName) {
const original = this.wasm.exports[functionName];
if (!original) {
throw new Error(`Function ${functionName} not found`);
}
return (...args) => {
const start = performance.now();
const memoryBefore = this._getMemoryUsage();
const result = original.apply(this.wasm.exports, args);
const end = performance.now();
const memoryAfter = this._getMemoryUsage();
this._recordMetric(functionName, {
duration: end - start,
memoryDelta: memoryAfter - memoryBefore,
timestamp: Date.now()
});
return result;
};
}
_getMemoryUsage() {
const pages = this.wasm.exports.memory.buffer.byteLength / 65536;
return pages;
}
_recordMetric(name, metric) {
if (!this.metrics.has(name)) {
this.metrics.set(name, []);
}
this.metrics.get(name).push(metric);
}
getStats(functionName) {
const metrics = this.metrics.get(functionName);
if (!metrics) return null;
const durations = metrics.map(m => m.duration);
const memoryDeltas = metrics.map(m => m.memoryDelta);
return {
count: metrics.length,
avgDuration: durations.reduce((a, b) => a + b, 0) / durations.length,
minDuration: Math.min(...durations),
maxDuration: Math.max(...durations),
avgMemoryDelta: memoryDeltas.reduce((a, b) => a + b, 0) / memoryDeltas.length
};
}
report() {
console.table(
Array.from(this.metrics.keys()).map(name => ({
function: name,
...this.getStats(name)
}))
);
}
}
|