@buoy-gg/benchmark 2.1.4-beta.2 → 2.1.4
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/lib/commonjs/benchmarking/BenchmarkComparator.js +1 -221
- package/lib/commonjs/benchmarking/BenchmarkRecorder.js +1 -497
- package/lib/commonjs/benchmarking/BenchmarkStorage.js +1 -235
- package/lib/commonjs/benchmarking/index.js +1 -83
- package/lib/commonjs/benchmarking/types.js +1 -13
- package/lib/commonjs/components/BenchmarkCompareView.js +1 -475
- package/lib/commonjs/components/BenchmarkDetailView.js +1 -346
- package/lib/commonjs/components/BenchmarkModal.js +1 -505
- package/lib/commonjs/components/BenchmarkSessionCard.js +1 -193
- package/lib/commonjs/index.js +1 -62
- package/lib/commonjs/preset.js +1 -86
- package/lib/module/benchmarking/BenchmarkComparator.js +1 -216
- package/lib/module/benchmarking/BenchmarkRecorder.js +1 -493
- package/lib/module/benchmarking/BenchmarkStorage.js +1 -227
- package/lib/module/benchmarking/index.js +1 -48
- package/lib/module/benchmarking/types.js +1 -13
- package/lib/module/components/BenchmarkCompareView.js +1 -469
- package/lib/module/components/BenchmarkDetailView.js +1 -340
- package/lib/module/components/BenchmarkModal.js +1 -499
- package/lib/module/components/BenchmarkSessionCard.js +1 -187
- package/lib/module/index.js +1 -39
- package/lib/module/preset.js +1 -81
- package/package.json +2 -2
- package/lib/typescript/benchmarking/BenchmarkComparator.d.ts.map +0 -1
- package/lib/typescript/benchmarking/BenchmarkRecorder.d.ts.map +0 -1
- package/lib/typescript/benchmarking/BenchmarkStorage.d.ts.map +0 -1
- package/lib/typescript/benchmarking/index.d.ts.map +0 -1
- package/lib/typescript/benchmarking/types.d.ts.map +0 -1
- package/lib/typescript/components/BenchmarkCompareView.d.ts.map +0 -1
- package/lib/typescript/components/BenchmarkDetailView.d.ts.map +0 -1
- package/lib/typescript/components/BenchmarkModal.d.ts.map +0 -1
- package/lib/typescript/components/BenchmarkSessionCard.d.ts.map +0 -1
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/preset.d.ts.map +0 -1
|
@@ -1,221 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* BenchmarkComparator
|
|
3
|
-
*
|
|
4
|
-
* Compares two benchmark reports and generates a detailed comparison result.
|
|
5
|
-
* Calculates improvements/regressions across all metrics and provides
|
|
6
|
-
* human-readable summaries.
|
|
7
|
-
*
|
|
8
|
-
* Usage:
|
|
9
|
-
* const comparison = BenchmarkComparator.compare(baselineReport, comparisonReport);
|
|
10
|
-
* console.log(comparison.summary);
|
|
11
|
-
* console.log(`Overall improvement: ${comparison.overallImprovement.toFixed(1)}%`);
|
|
12
|
-
*
|
|
13
|
-
* @packageDocumentation
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
"use strict";
|
|
17
|
-
|
|
18
|
-
Object.defineProperty(exports, "__esModule", {
|
|
19
|
-
value: true
|
|
20
|
-
});
|
|
21
|
-
exports.default = exports.BenchmarkComparator = void 0;
|
|
22
|
-
/**
|
|
23
|
-
* Calculate percentage improvement (positive = better)
|
|
24
|
-
* @param baseline - The baseline value
|
|
25
|
-
* @param comparison - The comparison value
|
|
26
|
-
* @returns Percentage improvement (positive = faster/better, negative = slower/worse)
|
|
27
|
-
*/
|
|
28
|
-
function calculateImprovement(baseline, comparison) {
|
|
29
|
-
if (baseline === 0) return 0;
|
|
30
|
-
return (baseline - comparison) / baseline * 100;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Format a percentage with sign
|
|
35
|
-
*/
|
|
36
|
-
function formatPercent(value) {
|
|
37
|
-
const sign = value >= 0 ? "+" : "";
|
|
38
|
-
return `${sign}${value.toFixed(1)}%`;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Format milliseconds
|
|
43
|
-
*/
|
|
44
|
-
function formatMs(value) {
|
|
45
|
-
return `${value.toFixed(1)}ms`;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Format bytes as MB
|
|
50
|
-
*/
|
|
51
|
-
function formatBytes(bytes) {
|
|
52
|
-
const mb = bytes / 1024 / 1024;
|
|
53
|
-
const sign = mb >= 0 ? "+" : "";
|
|
54
|
-
return `${sign}${mb.toFixed(2)}MB`;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Get an emoji indicator for improvement
|
|
59
|
-
*/
|
|
60
|
-
function getIndicator(improvement, threshold = 5) {
|
|
61
|
-
if (improvement > threshold) return "✅";
|
|
62
|
-
if (improvement < -threshold) return "❌";
|
|
63
|
-
return "➖";
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* BenchmarkComparator - Compares two benchmark reports
|
|
68
|
-
*/
|
|
69
|
-
class BenchmarkComparator {
|
|
70
|
-
/**
|
|
71
|
-
* Compare two benchmark reports
|
|
72
|
-
* @param baseline - The baseline (before) report
|
|
73
|
-
* @param comparison - The comparison (after) report
|
|
74
|
-
* @returns Detailed comparison result
|
|
75
|
-
*/
|
|
76
|
-
static compare(baseline, comparison) {
|
|
77
|
-
const baselineStats = baseline.stats;
|
|
78
|
-
const comparisonStats = comparison.stats;
|
|
79
|
-
|
|
80
|
-
// Duration changes
|
|
81
|
-
const durationDelta = comparison.duration - baseline.duration;
|
|
82
|
-
const durationImprovement = calculateImprovement(baseline.duration, comparison.duration);
|
|
83
|
-
|
|
84
|
-
// Pipeline timing improvements
|
|
85
|
-
const filterTimeImprovement = calculateImprovement(baselineStats.avgFilterTime, comparisonStats.avgFilterTime);
|
|
86
|
-
const measureTimeImprovement = calculateImprovement(baselineStats.avgMeasureTime, comparisonStats.avgMeasureTime);
|
|
87
|
-
const trackTimeImprovement = calculateImprovement(baselineStats.avgTrackTime, comparisonStats.avgTrackTime);
|
|
88
|
-
const pipelineTimeImprovement = calculateImprovement(baselineStats.avgTotalTime, comparisonStats.avgTotalTime);
|
|
89
|
-
|
|
90
|
-
// Overlay render improvement
|
|
91
|
-
const overlayRenderImprovement = calculateImprovement(baselineStats.avgOverlayRenderTime, comparisonStats.avgOverlayRenderTime);
|
|
92
|
-
|
|
93
|
-
// Memory changes
|
|
94
|
-
let memoryDeltaChange = null;
|
|
95
|
-
if (baseline.memoryDelta != null && comparison.memoryDelta != null) {
|
|
96
|
-
memoryDeltaChange = comparison.memoryDelta - baseline.memoryDelta;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Overall improvement (weighted average of key metrics)
|
|
100
|
-
// Weights: measurement time (40%), pipeline time (30%), overlay render (20%), memory (10%)
|
|
101
|
-
const weights = {
|
|
102
|
-
measure: 0.4,
|
|
103
|
-
pipeline: 0.3,
|
|
104
|
-
overlay: 0.2,
|
|
105
|
-
memory: 0.1
|
|
106
|
-
};
|
|
107
|
-
let overallImprovement = measureTimeImprovement * weights.measure + pipelineTimeImprovement * weights.pipeline + overlayRenderImprovement * weights.overlay;
|
|
108
|
-
|
|
109
|
-
// Add memory improvement if available
|
|
110
|
-
if (baseline.memoryDelta != null && comparison.memoryDelta != null && baseline.memoryDelta !== 0) {
|
|
111
|
-
const memoryImprovement = calculateImprovement(baseline.memoryDelta, comparison.memoryDelta);
|
|
112
|
-
overallImprovement += memoryImprovement * weights.memory;
|
|
113
|
-
}
|
|
114
|
-
const isImproved = overallImprovement > 0;
|
|
115
|
-
|
|
116
|
-
// Generate summary
|
|
117
|
-
const summary = this.generateSummary({
|
|
118
|
-
baseline,
|
|
119
|
-
comparison,
|
|
120
|
-
durationDelta,
|
|
121
|
-
durationImprovement,
|
|
122
|
-
measureTimeImprovement,
|
|
123
|
-
pipelineTimeImprovement,
|
|
124
|
-
overlayRenderImprovement,
|
|
125
|
-
memoryDeltaChange,
|
|
126
|
-
overallImprovement,
|
|
127
|
-
isImproved
|
|
128
|
-
});
|
|
129
|
-
return {
|
|
130
|
-
baselineId: baseline.id,
|
|
131
|
-
baselineName: baseline.name,
|
|
132
|
-
comparisonId: comparison.id,
|
|
133
|
-
comparisonName: comparison.name,
|
|
134
|
-
comparedAt: Date.now(),
|
|
135
|
-
durationDelta,
|
|
136
|
-
durationImprovement,
|
|
137
|
-
filterTimeImprovement,
|
|
138
|
-
measureTimeImprovement,
|
|
139
|
-
trackTimeImprovement,
|
|
140
|
-
pipelineTimeImprovement,
|
|
141
|
-
overlayRenderImprovement,
|
|
142
|
-
memoryDeltaChange,
|
|
143
|
-
overallImprovement,
|
|
144
|
-
isImproved,
|
|
145
|
-
summary
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Generate a human-readable summary
|
|
151
|
-
*/
|
|
152
|
-
static generateSummary(data) {
|
|
153
|
-
const {
|
|
154
|
-
baseline,
|
|
155
|
-
comparison,
|
|
156
|
-
measureTimeImprovement,
|
|
157
|
-
pipelineTimeImprovement,
|
|
158
|
-
overlayRenderImprovement,
|
|
159
|
-
memoryDeltaChange,
|
|
160
|
-
overallImprovement,
|
|
161
|
-
isImproved
|
|
162
|
-
} = data;
|
|
163
|
-
const lines = [];
|
|
164
|
-
lines.push("╔══════════════════════════════════════════════════════════════╗");
|
|
165
|
-
lines.push("║ BENCHMARK COMPARISON ║");
|
|
166
|
-
lines.push("╠══════════════════════════════════════════════════════════════╣");
|
|
167
|
-
lines.push(`║ Baseline: ${baseline.name.substring(0, 50).padEnd(50)} ║`);
|
|
168
|
-
lines.push(`║ ${new Date(baseline.createdAt).toLocaleString().substring(0, 58).padEnd(58)} ║`);
|
|
169
|
-
lines.push(`║ Comparison: ${comparison.name.substring(0, 48).padEnd(48)} ║`);
|
|
170
|
-
lines.push(`║ ${new Date(comparison.createdAt).toLocaleString().substring(0, 58).padEnd(58)} ║`);
|
|
171
|
-
lines.push("╠══════════════════════════════════════════════════════════════╣");
|
|
172
|
-
lines.push("║ TIMING COMPARISON ║");
|
|
173
|
-
lines.push("║ Baseline After Change ║");
|
|
174
|
-
lines.push(`║ Measurement Time: ${formatMs(baseline.stats.avgMeasureTime).padStart(8)} → ` + `${formatMs(comparison.stats.avgMeasureTime).padStart(8)} ` + `${formatPercent(measureTimeImprovement).padStart(7)} ${getIndicator(measureTimeImprovement)} ║`);
|
|
175
|
-
lines.push(`║ Pipeline Time: ${formatMs(baseline.stats.avgTotalTime).padStart(8)} → ` + `${formatMs(comparison.stats.avgTotalTime).padStart(8)} ` + `${formatPercent(pipelineTimeImprovement).padStart(7)} ${getIndicator(pipelineTimeImprovement)} ║`);
|
|
176
|
-
lines.push(`║ Overlay Render: ${formatMs(baseline.stats.avgOverlayRenderTime).padStart(8)} → ` + `${formatMs(comparison.stats.avgOverlayRenderTime).padStart(8)} ` + `${formatPercent(overlayRenderImprovement).padStart(7)} ${getIndicator(overlayRenderImprovement)} ║`);
|
|
177
|
-
if (memoryDeltaChange != null && baseline.memoryDelta != null && comparison.memoryDelta != null) {
|
|
178
|
-
const memoryImprovement = calculateImprovement(baseline.memoryDelta, comparison.memoryDelta);
|
|
179
|
-
lines.push("╠══════════════════════════════════════════════════════════════╣");
|
|
180
|
-
lines.push("║ MEMORY ║");
|
|
181
|
-
lines.push(`║ Delta: ${formatBytes(baseline.memoryDelta).padStart(8)} → ` + `${formatBytes(comparison.memoryDelta).padStart(8)} ` + `${formatPercent(memoryImprovement).padStart(7)} ${getIndicator(memoryImprovement)} ║`);
|
|
182
|
-
}
|
|
183
|
-
lines.push("╠══════════════════════════════════════════════════════════════╣");
|
|
184
|
-
lines.push("║ PERCENTILES (P95) ║");
|
|
185
|
-
const p95Improvement = calculateImprovement(baseline.stats.p95TotalTime, comparison.stats.p95TotalTime);
|
|
186
|
-
lines.push(`║ P95 Pipeline: ${formatMs(baseline.stats.p95TotalTime).padStart(8)} → ` + `${formatMs(comparison.stats.p95TotalTime).padStart(8)} ` + `${formatPercent(p95Improvement).padStart(7)} ${getIndicator(p95Improvement)} ║`);
|
|
187
|
-
lines.push("╠══════════════════════════════════════════════════════════════╣");
|
|
188
|
-
const resultEmoji = isImproved ? "🎉" : "⚠️";
|
|
189
|
-
const resultText = isImproved ? "IMPROVED" : "REGRESSED";
|
|
190
|
-
lines.push(`║ ${resultEmoji} OVERALL: ${formatPercent(overallImprovement).padStart(7)} ${resultText.padEnd(40)} ║`);
|
|
191
|
-
lines.push("╚══════════════════════════════════════════════════════════════╝");
|
|
192
|
-
return lines.join("\n");
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Log a comparison to the console
|
|
197
|
-
*/
|
|
198
|
-
static logComparison(comparison) {
|
|
199
|
-
console.log("\n" + comparison.summary + "\n");
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Quick compare: compare baseline vs comparison and log results
|
|
204
|
-
*/
|
|
205
|
-
static quickCompare(baseline, comparison) {
|
|
206
|
-
const result = this.compare(baseline, comparison);
|
|
207
|
-
this.logComparison(result);
|
|
208
|
-
return result;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Generate a brief one-line summary
|
|
213
|
-
*/
|
|
214
|
-
static getBriefSummary(comparison) {
|
|
215
|
-
const direction = comparison.isImproved ? "faster" : "slower";
|
|
216
|
-
const emoji = comparison.isImproved ? "✅" : "❌";
|
|
217
|
-
return `${emoji} ${Math.abs(comparison.overallImprovement).toFixed(1)}% ${direction} (measurement: ${formatPercent(comparison.measureTimeImprovement)}, pipeline: ${formatPercent(comparison.pipelineTimeImprovement)})`;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
exports.BenchmarkComparator = BenchmarkComparator;
|
|
221
|
-
var _default = exports.default = BenchmarkComparator;
|
|
1
|
+
"use strict";function calculateImprovement(e,t){return 0===e?0:(e-t)/e*100}function formatPercent(e){return`${e>=0?"+":""}${e.toFixed(1)}%`}function formatMs(e){return`${e.toFixed(1)}ms`}function formatBytes(e){const t=e/1024/1024;return`${t>=0?"+":""}${t.toFixed(2)}MB`}function getIndicator(e,t=5){return e>t?"✅":e<-t?"❌":"➖"}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=exports.BenchmarkComparator=void 0;class BenchmarkComparator{static compare(e,t){const a=e.stats,r=t.stats,m=t.duration-e.duration,o=calculateImprovement(e.duration,t.duration),n=calculateImprovement(a.avgFilterTime,r.avgFilterTime),s=calculateImprovement(a.avgMeasureTime,r.avgMeasureTime),p=calculateImprovement(a.avgTrackTime,r.avgTrackTime),i=calculateImprovement(a.avgTotalTime,r.avgTotalTime),l=calculateImprovement(a.avgOverlayRenderTime,r.avgOverlayRenderTime);let u=null;null!=e.memoryDelta&&null!=t.memoryDelta&&(u=t.memoryDelta-e.memoryDelta);let c=.4*s+.3*i+.2*l;null!=e.memoryDelta&&null!=t.memoryDelta&&0!==e.memoryDelta&&(c+=.1*calculateImprovement(e.memoryDelta,t.memoryDelta));const d=c>0,v=this.generateSummary({baseline:e,comparison:t,durationDelta:m,durationImprovement:o,measureTimeImprovement:s,pipelineTimeImprovement:i,overlayRenderImprovement:l,memoryDeltaChange:u,overallImprovement:c,isImproved:d});return{baselineId:e.id,baselineName:e.name,comparisonId:t.id,comparisonName:t.name,comparedAt:Date.now(),durationDelta:m,durationImprovement:o,filterTimeImprovement:n,measureTimeImprovement:s,trackTimeImprovement:p,pipelineTimeImprovement:i,overlayRenderImprovement:l,memoryDeltaChange:u,overallImprovement:c,isImproved:d,summary:v}}static generateSummary(e){const{baseline:t,comparison:a,measureTimeImprovement:r,pipelineTimeImprovement:m,overlayRenderImprovement:o,memoryDeltaChange:n,overallImprovement:s,isImproved:p}=e,i=[];if(i.push("╔══════════════════════════════════════════════════════════════╗"),i.push("║ BENCHMARK COMPARISON ║"),i.push("╠══════════════════════════════════════════════════════════════╣"),i.push(`║ Baseline: ${t.name.substring(0,50).padEnd(50)} ║`),i.push(`║ ${new Date(t.createdAt).toLocaleString().substring(0,58).padEnd(58)} ║`),i.push(`║ Comparison: ${a.name.substring(0,48).padEnd(48)} ║`),i.push(`║ ${new Date(a.createdAt).toLocaleString().substring(0,58).padEnd(58)} ║`),i.push("╠══════════════════════════════════════════════════════════════╣"),i.push("║ TIMING COMPARISON ║"),i.push("║ Baseline After Change ║"),i.push(`║ Measurement Time: ${formatMs(t.stats.avgMeasureTime).padStart(8)} → ${formatMs(a.stats.avgMeasureTime).padStart(8)} ${formatPercent(r).padStart(7)} ${getIndicator(r)} ║`),i.push(`║ Pipeline Time: ${formatMs(t.stats.avgTotalTime).padStart(8)} → ${formatMs(a.stats.avgTotalTime).padStart(8)} ${formatPercent(m).padStart(7)} ${getIndicator(m)} ║`),i.push(`║ Overlay Render: ${formatMs(t.stats.avgOverlayRenderTime).padStart(8)} → ${formatMs(a.stats.avgOverlayRenderTime).padStart(8)} ${formatPercent(o).padStart(7)} ${getIndicator(o)} ║`),null!=n&&null!=t.memoryDelta&&null!=a.memoryDelta){const e=calculateImprovement(t.memoryDelta,a.memoryDelta);i.push("╠══════════════════════════════════════════════════════════════╣"),i.push("║ MEMORY ║"),i.push(`║ Delta: ${formatBytes(t.memoryDelta).padStart(8)} → ${formatBytes(a.memoryDelta).padStart(8)} ${formatPercent(e).padStart(7)} ${getIndicator(e)} ║`)}i.push("╠══════════════════════════════════════════════════════════════╣"),i.push("║ PERCENTILES (P95) ║");const l=calculateImprovement(t.stats.p95TotalTime,a.stats.p95TotalTime);i.push(`║ P95 Pipeline: ${formatMs(t.stats.p95TotalTime).padStart(8)} → ${formatMs(a.stats.p95TotalTime).padStart(8)} ${formatPercent(l).padStart(7)} ${getIndicator(l)} ║`),i.push("╠══════════════════════════════════════════════════════════════╣");const u=p?"🎉":"⚠️",c=p?"IMPROVED":"REGRESSED";return i.push(`║ ${u} OVERALL: ${formatPercent(s).padStart(7)} ${c.padEnd(40)} ║`),i.push("╚══════════════════════════════════════════════════════════════╝"),i.join("\n")}static logComparison(e){console.log("\n"+e.summary+"\n")}static quickCompare(e,t){const a=this.compare(e,t);return this.logComparison(a),a}static getBriefSummary(e){const t=e.isImproved?"faster":"slower";return`${e.isImproved?"✅":"❌"} ${Math.abs(e.overallImprovement).toFixed(1)}% ${t} (measurement: ${formatPercent(e.measureTimeImprovement)}, pipeline: ${formatPercent(e.pipelineTimeImprovement)})`}}exports.BenchmarkComparator=BenchmarkComparator;var _default=exports.default=BenchmarkComparator;
|