mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
perf(ext/web): optimize performance.measure() (#25774)
This PR optimizes the case when `performance.measure()` needs to find the startMark by name. It is a simple change on `findMostRecent` fn to avoiding copying and reversing the complete entries list. Adds minor missing tests for: - `clearMarks()`, general - `clearMeasures()`, general - `measure()`, case when the startMarks name exists more than once ### Benchmarks #### main ``` CPU | AMD Ryzen 7 PRO 6850U with Radeon Graphics Runtime | Deno 2.0.0-rc.4 (x86_64-unknown-linux-gnu) benchmark time/iter (avg) iter/s (min … max) p75 p99 p995 ---------------------- ----------------------------- --------------------- -------------------------- worst case measure() 2.1 ms 486.9 ( 1.7 ms … 2.4 ms) 2.2 ms 2.4 ms 2.4 ms ``` #### this PR ``` CPU | AMD Ryzen 7 PRO 6850U with Radeon Graphics Runtime | Deno 2.0.0-rc.4 (x86_64-unknown-linux-gnu) benchmark time/iter (avg) iter/s (min … max) p75 p99 p995 ---------------------- ----------------------------- --------------------- -------------------------- worst case measure() 966.3 µs 1,035 (876.9 µs … 1.1 ms) 1.0 ms 1.1 ms 1.1 ms ``` ```ts Deno.bench("worst case measure()", (b) => { performance.mark('start'); for (let i = 0; i < 1e5; i += 1) { performance.mark(crypto.randomUUID()); } b.start(); performance.measure('total', 'start'); b.end(); performance.clearMarks(); performance.clearMeasures(); }); ```
This commit is contained in:
parent
55c22ee1bd
commit
88a469e823
2 changed files with 61 additions and 7 deletions
|
@ -3,10 +3,7 @@
|
||||||
import { primordials } from "ext:core/mod.js";
|
import { primordials } from "ext:core/mod.js";
|
||||||
const {
|
const {
|
||||||
ArrayPrototypeFilter,
|
ArrayPrototypeFilter,
|
||||||
ArrayPrototypeFind,
|
|
||||||
ArrayPrototypePush,
|
ArrayPrototypePush,
|
||||||
ArrayPrototypeReverse,
|
|
||||||
ArrayPrototypeSlice,
|
|
||||||
ObjectKeys,
|
ObjectKeys,
|
||||||
ObjectPrototypeIsPrototypeOf,
|
ObjectPrototypeIsPrototypeOf,
|
||||||
ReflectHas,
|
ReflectHas,
|
||||||
|
@ -101,10 +98,12 @@ function findMostRecent(
|
||||||
name,
|
name,
|
||||||
type,
|
type,
|
||||||
) {
|
) {
|
||||||
return ArrayPrototypeFind(
|
for (let i = performanceEntries.length - 1; i >= 0; --i) {
|
||||||
ArrayPrototypeReverse(ArrayPrototypeSlice(performanceEntries)),
|
const entry = performanceEntries[i];
|
||||||
(entry) => entry.name === name && entry.entryType === type,
|
if (entry.name === name && entry.entryType === type) {
|
||||||
);
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertMarkToTimestamp(mark) {
|
function convertMarkToTimestamp(mark) {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import {
|
import {
|
||||||
assert,
|
assert,
|
||||||
assertEquals,
|
assertEquals,
|
||||||
|
assertNotEquals,
|
||||||
assertNotStrictEquals,
|
assertNotStrictEquals,
|
||||||
assertStringIncludes,
|
assertStringIncludes,
|
||||||
assertThrows,
|
assertThrows,
|
||||||
|
@ -36,6 +37,41 @@ Deno.test(function performanceToJSON() {
|
||||||
assertEquals(Object.keys(json).length, 1);
|
assertEquals(Object.keys(json).length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test(function clearMarks() {
|
||||||
|
performance.mark("a");
|
||||||
|
performance.mark("a");
|
||||||
|
performance.mark("b");
|
||||||
|
performance.mark("c");
|
||||||
|
|
||||||
|
const marksNum = performance.getEntriesByType("mark").length;
|
||||||
|
|
||||||
|
performance.clearMarks("a");
|
||||||
|
assertEquals(performance.getEntriesByType("mark").length, marksNum - 2);
|
||||||
|
|
||||||
|
performance.clearMarks();
|
||||||
|
assertEquals(performance.getEntriesByType("mark").length, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test(function clearMeasures() {
|
||||||
|
performance.measure("from-start");
|
||||||
|
performance.mark("a");
|
||||||
|
performance.measure("from-mark-a", "a");
|
||||||
|
performance.measure("from-start");
|
||||||
|
performance.measure("from-mark-a", "a");
|
||||||
|
performance.mark("b");
|
||||||
|
performance.measure("between-a-and-b", "a", "b");
|
||||||
|
|
||||||
|
const measuresNum = performance.getEntriesByType("measure").length;
|
||||||
|
|
||||||
|
performance.clearMeasures("from-start");
|
||||||
|
assertEquals(performance.getEntriesByType("measure").length, measuresNum - 2);
|
||||||
|
|
||||||
|
performance.clearMeasures();
|
||||||
|
assertEquals(performance.getEntriesByType("measure").length, 0);
|
||||||
|
|
||||||
|
performance.clearMarks();
|
||||||
|
});
|
||||||
|
|
||||||
Deno.test(function performanceMark() {
|
Deno.test(function performanceMark() {
|
||||||
const mark = performance.mark("test");
|
const mark = performance.mark("test");
|
||||||
assert(mark instanceof PerformanceMark);
|
assert(mark instanceof PerformanceMark);
|
||||||
|
@ -127,6 +163,25 @@ Deno.test(function performanceMeasure() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test(function performanceMeasureUseMostRecentMark() {
|
||||||
|
const markName1 = "mark1";
|
||||||
|
const measureName1 = "measure1";
|
||||||
|
const mark1 = performance.mark(markName1);
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
try {
|
||||||
|
const laterMark1 = performance.mark(markName1);
|
||||||
|
const measure1 = performance.measure(measureName1, markName1);
|
||||||
|
assertNotEquals(mark1.startTime, measure1.startTime);
|
||||||
|
assertEquals(laterMark1.startTime, measure1.startTime);
|
||||||
|
} catch (e) {
|
||||||
|
return reject(e);
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
Deno.test(function performanceCustomInspectFunction() {
|
Deno.test(function performanceCustomInspectFunction() {
|
||||||
assertStringIncludes(Deno.inspect(performance), "Performance");
|
assertStringIncludes(Deno.inspect(performance), "Performance");
|
||||||
assertStringIncludes(
|
assertStringIncludes(
|
||||||
|
|
Loading…
Reference in a new issue