Skip to content

Commit

Permalink
Update ByteEfficiencyAudits to use log-normal distribution scoring (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
robatron committed May 20, 2023
1 parent 9922e4c commit f76e799
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 26 deletions.
33 changes: 14 additions & 19 deletions core/audits/byte-efficiency/byte-efficiency-audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/

import {Audit} from '../audit.js';
import {linearInterpolation} from '../../lib/statistics.js';
import {LanternInteractive} from '../../computed/metrics/lantern-interactive.js';
import * as i18n from '../../lib/i18n/i18n.js';
import {NetworkRecords} from '../../computed/network-records.js';
Expand All @@ -17,9 +16,13 @@ const str_ = i18n.createIcuMessageFn(import.meta.url, {});
/** @typedef {import('../../lib/dependency-graph/simulator/simulator').Simulator} Simulator */
/** @typedef {import('../../lib/dependency-graph/base-node.js').Node} Node */

const WASTED_MS_FOR_AVERAGE = 300;
const WASTED_MS_FOR_POOR = 750;
const WASTED_MS_FOR_SCORE_OF_ZERO = 5000;
// Parameters for log-normal distribution scoring. These values were determined by fitting the
// log-normal cumulative distribution function curve to the former method of linear interpolation
// scoring between the control points {average = 300 ms, poor = 750 ms, zero = 5000 ms} using the
// curve-fit tool at https://mycurvefit.com/ rounded to the nearest integer. See
// https://www.desmos.com/calculator/gcexiyesdi for an interactive visualization of the curve fit.
const WASTED_MS_P10 = 150;
const WASTED_MS_MEDIAN = 935;

/**
* @typedef {object} ByteEfficiencyProduct
Expand All @@ -38,26 +41,18 @@ const WASTED_MS_FOR_SCORE_OF_ZERO = 5000;
*/
class ByteEfficiencyAudit extends Audit {
/**
* Creates a score based on the wastedMs value using linear interpolation between control points.
* A negative wastedMs is scored as 1, assuming time is not being wasted with respect to the
* opportunity being measured.
* Creates a score based on the wastedMs value using log-normal distribution scoring. A negative
* wastedMs will be scored as 1, assuming time is not being wasted with respect to the opportunity
* being measured.
*
* @param {number} wastedMs
* @return {number}
*/
static scoreForWastedMs(wastedMs) {
if (wastedMs <= 0) {
return 1;
} else if (wastedMs < WASTED_MS_FOR_AVERAGE) {
return linearInterpolation(0, 1, WASTED_MS_FOR_AVERAGE, 0.75, wastedMs);
} else if (wastedMs < WASTED_MS_FOR_POOR) {
return linearInterpolation(WASTED_MS_FOR_AVERAGE, 0.75, WASTED_MS_FOR_POOR, 0.5, wastedMs);
} else {
return Math.max(
0,
linearInterpolation(WASTED_MS_FOR_POOR, 0.5, WASTED_MS_FOR_SCORE_OF_ZERO, 0, wastedMs)
);
}
return Audit.computeLogNormalScore(
{p10: WASTED_MS_P10, median: WASTED_MS_MEDIAN},
wastedMs
);
}

/**
Expand Down
15 changes: 8 additions & 7 deletions core/test/audits/byte-efficiency/byte-efficiency-audit-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -414,13 +414,14 @@ describe('Byte efficiency base audit', () => {
it('scores wastedMs values', () => {
expect(ByteEfficiencyAudit.scoreForWastedMs(-50)).toBe(1);
expect(ByteEfficiencyAudit.scoreForWastedMs(0)).toBe(1);
expect(ByteEfficiencyAudit.scoreForWastedMs(240)).toBe(0.8);
expect(ByteEfficiencyAudit.scoreForWastedMs(300)).toBe(0.75);
expect(ByteEfficiencyAudit.scoreForWastedMs(390)).toBe(0.7);
expect(ByteEfficiencyAudit.scoreForWastedMs(750)).toBe(0.5);
expect(ByteEfficiencyAudit.scoreForWastedMs(1_175)).toBe(0.45);
expect(ByteEfficiencyAudit.scoreForWastedMs(5_000)).toBe(0);
expect(ByteEfficiencyAudit.scoreForWastedMs(10_000)).toBe(0);
expect(ByteEfficiencyAudit.scoreForWastedMs(240)).toBe(0.82);
expect(ByteEfficiencyAudit.scoreForWastedMs(300)).toBe(0.78);
expect(ByteEfficiencyAudit.scoreForWastedMs(390)).toBe(0.72);
expect(ByteEfficiencyAudit.scoreForWastedMs(750)).toBe(0.56);
expect(ByteEfficiencyAudit.scoreForWastedMs(1_175)).toBe(0.43);
expect(ByteEfficiencyAudit.scoreForWastedMs(5_000)).toBe(0.12);
expect(ByteEfficiencyAudit.scoreForWastedMs(10_000)).toBe(0.04);
expect(ByteEfficiencyAudit.scoreForWastedMs(30_000)).toBe(0);
expect(ByteEfficiencyAudit.scoreForWastedMs(Number.MAX_VALUE)).toBe(0);
});
});
Expand Down

0 comments on commit f76e799

Please sign in to comment.