perfshield 0.0.1 → 0.0.3

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/README.md CHANGED
@@ -62,10 +62,7 @@ export const benchmarks = [
62
62
  "sampling": {
63
63
  "minSamples": 30,
64
64
  "timeoutMs": 10000,
65
- "conditions": {
66
- "absolute": [0],
67
- "relative": [0]
68
- }
65
+ "conditions": [0]
69
66
  },
70
67
  "report": {
71
68
  "formats": ["console", "json"]
@@ -13,10 +13,7 @@
13
13
  "sampling": {
14
14
  "minSamples": 30,
15
15
  "timeoutMs": 10000,
16
- "conditions": {
17
- "absolute": [0],
18
- "relative": [0]
19
- }
16
+ "conditions": [0]
20
17
  },
21
18
  "report": {
22
19
  "formats": ["console", "json"]
package/lib/config.js CHANGED
@@ -158,26 +158,6 @@ const parseEngineConfig = (value, index, issues) => {
158
158
  name
159
159
  };
160
160
  };
161
- const parseSamplingConditions = (value, issues) => {
162
- const conditions = asObject(value, "config.sampling.conditions", issues);
163
- if (!conditions) {
164
- return null;
165
- }
166
- validateKeys(conditions, ["absolute", "relative"], "config.sampling.conditions", issues);
167
- const absolute = asNumberArray(conditions.absolute, "config.sampling.conditions.absolute", issues, {
168
- minLength: 1
169
- });
170
- const relative = asNumberArray(conditions.relative, "config.sampling.conditions.relative", issues, {
171
- minLength: 1
172
- });
173
- if (!absolute || !relative) {
174
- return null;
175
- }
176
- return {
177
- absolute,
178
- relative
179
- };
180
- };
181
161
  const parseSamplingConfig = (value, issues) => {
182
162
  const sampling = asObject(value, "config.sampling", issues);
183
163
  if (!sampling) {
@@ -192,7 +172,9 @@ const parseSamplingConfig = (value, issues) => {
192
172
  integer: true,
193
173
  min: 1
194
174
  });
195
- const conditions = parseSamplingConditions(sampling.conditions, issues);
175
+ const conditions = asNumberArray(sampling.conditions, "config.sampling.conditions", issues, {
176
+ minLength: 1
177
+ });
196
178
  if (minSamples == null || timeoutMs == null || !conditions) {
197
179
  return null;
198
180
  }
package/lib/regression.js CHANGED
@@ -3,9 +3,8 @@ export const getRegressions = results => {
3
3
  const findings = [];
4
4
  for (const result of results) {
5
5
  for (const entry of result.benchmarks) {
6
- if (isPositiveInterval(entry.difference.absolute.ci) || isPositiveInterval(entry.difference.relative.ci)) {
6
+ if (isPositiveInterval(entry.difference.relative.ci)) {
7
7
  findings.push({
8
- absolute: entry.difference.absolute.ci,
9
8
  benchmark: entry.benchmark.name,
10
9
  engine: result.engine.name,
11
10
  relative: entry.difference.relative.ci
@@ -16,7 +16,7 @@ export const renderConsoleReport = results => {
16
16
  lines.push(`Engine: ${result.engine.name}`);
17
17
  for (const entry of result.benchmarks) {
18
18
  const unit = entry.benchmark.unit != null ? ` ${entry.benchmark.unit}` : "";
19
- const benchmarkLines = [` Benchmark: ${entry.benchmark.name}`, ` baseline mean=${formatNumber(entry.stats.baseline.mean, 4)}${unit} ci=${formatInterval(entry.stats.baseline.meanCI, 4)} sd=${formatNumber(entry.stats.baseline.standardDeviation, 4)}`, ` current mean=${formatNumber(entry.stats.current.mean, 4)}${unit} ci=${formatInterval(entry.stats.current.meanCI, 4)} sd=${formatNumber(entry.stats.current.standardDeviation, 4)}`, ` diff abs mean=${formatNumber(entry.difference.absolute.mean, 4)}${unit} ci=${formatInterval(entry.difference.absolute.ci, 4)}`, ` diff rel mean=${formatRelativeValue(entry.difference.relative.mean, 2)} ci=${formatRelativeInterval(entry.difference.relative.ci, 2)}`];
19
+ const benchmarkLines = [` Benchmark: ${entry.benchmark.name}`, ` baseline mean=${formatNumber(entry.stats.baseline.mean, 4)}${unit} ci=${formatInterval(entry.stats.baseline.meanCI, 4)} sd=${formatNumber(entry.stats.baseline.standardDeviation, 4)}`, ` current mean=${formatNumber(entry.stats.current.mean, 4)}${unit} ci=${formatInterval(entry.stats.current.meanCI, 4)} sd=${formatNumber(entry.stats.current.standardDeviation, 4)}`, ` diff rel mean=${formatRelativeValue(entry.difference.relative.mean, 2)} ci=${formatRelativeInterval(entry.difference.relative.ci, 2)}`];
20
20
  lines.push(...benchmarkLines);
21
21
  }
22
22
  lines.push("");
package/lib/runner.js CHANGED
@@ -8,6 +8,12 @@ import { computeDifference, summaryStats } from "./stats.js";
8
8
  const versions = ["baseline", "current"];
9
9
  const autoSampleBatchSize = 10;
10
10
  const harnessTempPrefix = "perfshield-harness-";
11
+ const getVersionOrder = seed => {
12
+ if (seed % 2 === 0) {
13
+ return versions;
14
+ }
15
+ return [versions[1], versions[0]];
16
+ };
11
17
  const getHarnessPath = () => {
12
18
  const override = process.env.WEB_BENCHMARKER_HARNESS_PATH;
13
19
  if (override != null) {
@@ -70,10 +76,13 @@ const collectSamples = async (harness, benchmarks, minSamples) => {
70
76
  baseline: [],
71
77
  current: []
72
78
  }));
79
+ let roundRobinSeed = 0;
73
80
  for (let iteration = 0; iteration < minSamples; iteration += 1) {
74
81
  for (let index = 0; index < benchmarks.length; index += 1) {
75
82
  const descriptor = benchmarks[index];
76
- for (const version of versions) {
83
+ const order = getVersionOrder(roundRobinSeed);
84
+ roundRobinSeed += 1;
85
+ for (const version of order) {
77
86
  const result = await harness.runSample({
78
87
  index,
79
88
  iterations: descriptor.iterations,
@@ -94,12 +103,7 @@ const autoSampleResolved = (samples, conditions) => samples.every(bucket => {
94
103
  const baselineStats = summaryStats(bucket.baseline);
95
104
  const currentStats = summaryStats(bucket.current);
96
105
  const diff = computeDifference(baselineStats, currentStats);
97
- for (const condition of conditions.absolute) {
98
- if (intervalContains(diff.absolute.ci, condition)) {
99
- return false;
100
- }
101
- }
102
- for (const condition of conditions.relative) {
106
+ for (const condition of conditions) {
103
107
  if (intervalContains(diff.relative.ci, condition)) {
104
108
  return false;
105
109
  }
@@ -108,6 +112,7 @@ const autoSampleResolved = (samples, conditions) => samples.every(bucket => {
108
112
  });
109
113
  const autoSample = async (harness, benchmarks, samples, conditions, timeoutMs) => {
110
114
  const startTime = Date.now();
115
+ let roundRobinSeed = 0;
111
116
  while (Date.now() - startTime < timeoutMs) {
112
117
  if (autoSampleResolved(samples, conditions)) {
113
118
  return;
@@ -115,7 +120,9 @@ const autoSample = async (harness, benchmarks, samples, conditions, timeoutMs) =
115
120
  for (let batch = 0; batch < autoSampleBatchSize; batch += 1) {
116
121
  for (let index = 0; index < benchmarks.length; index += 1) {
117
122
  const descriptor = benchmarks[index];
118
- for (const version of versions) {
123
+ const order = getVersionOrder(roundRobinSeed);
124
+ roundRobinSeed += 1;
125
+ for (const version of order) {
119
126
  const result = await harness.runSample({
120
127
  index,
121
128
  iterations: descriptor.iterations,
package/lib/stats.js CHANGED
@@ -23,10 +23,6 @@ export const samplingDistributionOfTheMean = (distribution, sampleSize) => ({
23
23
  mean: distribution.mean,
24
24
  variance: distribution.variance / sampleSize
25
25
  });
26
- export const samplingDistributionOfAbsoluteDifferenceOfMeans = (a, b) => ({
27
- mean: b.mean - a.mean,
28
- variance: a.variance + b.variance
29
- });
30
26
  export const samplingDistributionOfRelativeDifferenceOfMeans = (a, b) => ({
31
27
  mean: (b.mean - a.mean) / a.mean,
32
28
  variance: (a.variance * b.mean * b.mean + b.variance * a.mean * a.mean) / (a.mean * a.mean * a.mean * a.mean)
@@ -65,14 +61,9 @@ export const computeDifference = (baseline, current) => {
65
61
  mean: current.mean,
66
62
  variance: current.variance
67
63
  }, current.size);
68
- const absoluteDist = samplingDistributionOfAbsoluteDifferenceOfMeans(baselineDist, currentDist);
69
64
  const relativeDist = samplingDistributionOfRelativeDifferenceOfMeans(baselineDist, currentDist);
70
65
  const size = Math.min(baseline.size, current.size);
71
66
  return {
72
- absolute: {
73
- ci: confidenceInterval95(absoluteDist, size),
74
- mean: absoluteDist.mean
75
- },
76
67
  relative: {
77
68
  ci: confidenceInterval95(relativeDist, size),
78
69
  mean: relativeDist.mean
@@ -92,12 +83,7 @@ export const autoSampleConditionsResolved = (resultStats, conditions) => {
92
83
  if (diff == null) {
93
84
  continue;
94
85
  }
95
- for (const condition of conditions.absolute) {
96
- if (intervalContains(diff.absolute.ci, condition)) {
97
- return false;
98
- }
99
- }
100
- for (const condition of conditions.relative) {
86
+ for (const condition of conditions) {
101
87
  if (intervalContains(diff.relative.ci, condition)) {
102
88
  return false;
103
89
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perfshield",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "A tool for doing web benchmarking across multiple JS engines and with statistical signifigance",
5
5
  "license": "MIT",
6
6
  "type": "module",