diff --git a/packages-user/data-base/src/hero/attribute.perf.ts b/packages-user/data-base/src/hero/attribute.perf.ts index e4b5509..c781414 100644 --- a/packages-user/data-base/src/hero/attribute.perf.ts +++ b/packages-user/data-base/src/hero/attribute.perf.ts @@ -107,7 +107,9 @@ interface PerfRecord { const records: PerfRecord[] = []; /** - * 测量一次用例:先预热若干次,再采样后取中位数、最小值与 p95 + * 测量一次用例:先预热若干次,再采样后取中位数、最小值与 p95, + * 计时经 performance.mark / performance.measure 成对标记完成, + * 采样后按名清理标记与测量 * @param caseName 测量项名称 * @param scale 规模档位 * @param run 单次被测量的操作 @@ -121,11 +123,25 @@ function measureCase( run(); } + // 必须先打标记再测量:对不存在的标记做 measure 会抛错; + // 标记还必须逐样本清理,否则同名标记会被解析成首次位置而得到累计耗时 + const startTag = 'perf:' + caseName + ':' + scale + ':start'; + const endTag = 'perf:' + caseName + ':' + scale + ':end'; + const measureName = 'perf:' + caseName + ':' + scale; const samples: number[] = []; for (let i = 0; i < SAMPLE_RUNS; i++) { - const start = globalThis.performance.now(); + globalThis.performance.mark(startTag); run(); - samples.push(globalThis.performance.now() - start); + globalThis.performance.mark(endTag); + const measure = globalThis.performance.measure( + measureName, + startTag, + endTag + ); + samples.push(measure.duration); + globalThis.performance.clearMarks(startTag); + globalThis.performance.clearMarks(endTag); + globalThis.performance.clearMeasures(measureName); } samples.sort((left, right) => left - right); diff --git a/packages-user/data-state/test/saveables.perf.ts b/packages-user/data-state/test/saveables.perf.ts index cf7307e..5c6f3f5 100644 --- a/packages-user/data-state/test/saveables.perf.ts +++ b/packages-user/data-state/test/saveables.perf.ts @@ -77,7 +77,9 @@ interface PerfRecord { const records: PerfRecord[] = []; /** - * 测量一次用例:先预热若干次,再采样后取中位数、最小值与 p95 + * 测量一次用例:先预热若干次,再采样后取中位数、最小值与 p95, + * 计时经 performance.mark / performance.measure 成对标记完成, + * 采样后按名清理标记与测量 * @param caseName 测量项名称 * @param scale 规模档位 * @param run 单次被测量的操作 @@ -91,11 +93,25 @@ function measureCase( run(); } + // 必须先打标记再测量:对不存在的标记做 measure 会抛错; + // 标记还必须逐样本清理,否则同名标记会被解析成首次位置而得到累计耗时 + const startTag = 'perf:' + caseName + ':' + scale + ':start'; + const endTag = 'perf:' + caseName + ':' + scale + ':end'; + const measureName = 'perf:' + caseName + ':' + scale; const samples: number[] = []; for (let i = 0; i < SAMPLE_RUNS; i++) { - const start = globalThis.performance.now(); + globalThis.performance.mark(startTag); run(); - samples.push(globalThis.performance.now() - start); + globalThis.performance.mark(endTag); + const measure = globalThis.performance.measure( + measureName, + startTag, + endTag + ); + samples.push(measure.duration); + globalThis.performance.clearMarks(startTag); + globalThis.performance.clearMarks(endTag); + globalThis.performance.clearMeasures(measureName); } samples.sort((left, right) => left - right); diff --git a/packages-user/data-state/test/saveablesReal.perf.ts b/packages-user/data-state/test/saveablesReal.perf.ts index a208d50..70b5be6 100644 --- a/packages-user/data-state/test/saveablesReal.perf.ts +++ b/packages-user/data-state/test/saveablesReal.perf.ts @@ -174,7 +174,9 @@ function clearCodes(flat: readonly number[]): number[] { } /** - * 测量一次用例:先预热若干次,再采样后取中位数、最小值与 p95 + * 测量一次用例:先预热若干次,再采样后取中位数、最小值与 p95, + * 计时经 performance.mark / performance.measure 成对标记完成, + * 采样后按名清理标记与测量 * @param caseName 测量项名称 * @param scale 规模档位 * @param run 单次被测量的操作 @@ -188,11 +190,25 @@ function measureCase( run(); } + // 必须先打标记再测量:对不存在的标记做 measure 会抛错; + // 标记还必须逐样本清理,否则同名标记会被解析成首次位置而得到累计耗时 + const startTag = 'perf:' + caseName + ':' + scale + ':start'; + const endTag = 'perf:' + caseName + ':' + scale + ':end'; + const measureName = 'perf:' + caseName + ':' + scale; const samples: number[] = []; for (let i = 0; i < SAMPLE_RUNS; i++) { - const start = globalThis.performance.now(); + globalThis.performance.mark(startTag); run(); - samples.push(globalThis.performance.now() - start); + globalThis.performance.mark(endTag); + const measure = globalThis.performance.measure( + measureName, + startTag, + endTag + ); + samples.push(measure.duration); + globalThis.performance.clearMarks(startTag); + globalThis.performance.clearMarks(endTag); + globalThis.performance.clearMeasures(measureName); } samples.sort((left, right) => left - right); diff --git a/packages-user/data-system/src/combat/context.perf.ts b/packages-user/data-system/src/combat/context.perf.ts index f7a8eda..fe7a1a3 100644 --- a/packages-user/data-system/src/combat/context.perf.ts +++ b/packages-user/data-system/src/combat/context.perf.ts @@ -106,7 +106,9 @@ interface PerfRecord { const records: PerfRecord[] = []; /** - * 测量一次用例:先预热若干次,再采样后取中位数、最小值与 p95 + * 测量一次用例:先预热若干次,再采样后取中位数、最小值与 p95, + * 计时经 performance.mark / performance.measure 成对标记完成, + * 采样后按名清理标记与测量 * @param caseName 测量项名称 * @param scale 规模档位 * @param run 单次被测量的操作 @@ -120,11 +122,25 @@ function measureCase( run(); } + // 必须先打标记再测量:对不存在的标记做 measure 会抛错; + // 标记还必须逐样本清理,否则同名标记会被解析成首次位置而得到累计耗时 + const startTag = 'perf:' + caseName + ':' + scale + ':start'; + const endTag = 'perf:' + caseName + ':' + scale + ':end'; + const measureName = 'perf:' + caseName + ':' + scale; const samples: number[] = []; for (let i = 0; i < SAMPLE_RUNS; i++) { - const start = globalThis.performance.now(); + globalThis.performance.mark(startTag); run(); - samples.push(globalThis.performance.now() - start); + globalThis.performance.mark(endTag); + const measure = globalThis.performance.measure( + measureName, + startTag, + endTag + ); + samples.push(measure.duration); + globalThis.performance.clearMarks(startTag); + globalThis.performance.clearMarks(endTag); + globalThis.performance.clearMeasures(measureName); } samples.sort((left, right) => left - right); diff --git a/packages-user/data-system/src/combat/damage.perf.ts b/packages-user/data-system/src/combat/damage.perf.ts index 9bdecd8..7abcb21 100644 --- a/packages-user/data-system/src/combat/damage.perf.ts +++ b/packages-user/data-system/src/combat/damage.perf.ts @@ -103,7 +103,9 @@ interface PerfRecord { const records: PerfRecord[] = []; /** - * 测量一次用例:先预热若干次,再采样后取中位数、最小值与 p95 + * 测量一次用例:先预热若干次,再采样后取中位数、最小值与 p95, + * 计时经 performance.mark / performance.measure 成对标记完成, + * 采样后按名清理标记与测量 * @param caseName 测量项名称 * @param scale 规模档位 * @param run 单次被测量的操作 @@ -117,11 +119,25 @@ function measureCase( run(); } + // 必须先打标记再测量:对不存在的标记做 measure 会抛错; + // 标记还必须逐样本清理,否则同名标记会被解析成首次位置而得到累计耗时 + const startTag = 'perf:' + caseName + ':' + scale + ':start'; + const endTag = 'perf:' + caseName + ':' + scale + ':end'; + const measureName = 'perf:' + caseName + ':' + scale; const samples: number[] = []; for (let i = 0; i < SAMPLE_RUNS; i++) { - const start = globalThis.performance.now(); + globalThis.performance.mark(startTag); run(); - samples.push(globalThis.performance.now() - start); + globalThis.performance.mark(endTag); + const measure = globalThis.performance.measure( + measureName, + startTag, + endTag + ); + samples.push(measure.duration); + globalThis.performance.clearMarks(startTag); + globalThis.performance.clearMarks(endTag); + globalThis.performance.clearMeasures(measureName); } samples.sort((left, right) => left - right);