summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcarles escrig royo <ce@thehotelsnetwork.com>2024-09-21 01:24:59 +0200
committerGitHub <noreply@github.com>2024-09-20 16:24:59 -0700
commit88a469e823658192daae1abe6f6e9bc14224c680 (patch)
tree34c5f971f5d41ab3551f3b5ba1cc08edcb58ae5d
parent55c22ee1bd8e5b108b8b13517150c3cfadf4d7f9 (diff)
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(); }); ```
-rw-r--r--ext/web/15_performance.js13
-rw-r--r--tests/unit/performance_test.ts55
2 files changed, 61 insertions, 7 deletions
diff --git a/ext/web/15_performance.js b/ext/web/15_performance.js
index 5045c0d31..ea5557278 100644
--- a/ext/web/15_performance.js
+++ b/ext/web/15_performance.js
@@ -3,10 +3,7 @@
import { primordials } from "ext:core/mod.js";
const {
ArrayPrototypeFilter,
- ArrayPrototypeFind,
ArrayPrototypePush,
- ArrayPrototypeReverse,
- ArrayPrototypeSlice,
ObjectKeys,
ObjectPrototypeIsPrototypeOf,
ReflectHas,
@@ -101,10 +98,12 @@ function findMostRecent(
name,
type,
) {
- return ArrayPrototypeFind(
- ArrayPrototypeReverse(ArrayPrototypeSlice(performanceEntries)),
- (entry) => entry.name === name && entry.entryType === type,
- );
+ for (let i = performanceEntries.length - 1; i >= 0; --i) {
+ const entry = performanceEntries[i];
+ if (entry.name === name && entry.entryType === type) {
+ return entry;
+ }
+ }
}
function convertMarkToTimestamp(mark) {
diff --git a/tests/unit/performance_test.ts b/tests/unit/performance_test.ts
index 93af641ad..fa056c7f5 100644
--- a/tests/unit/performance_test.ts
+++ b/tests/unit/performance_test.ts
@@ -2,6 +2,7 @@
import {
assert,
assertEquals,
+ assertNotEquals,
assertNotStrictEquals,
assertStringIncludes,
assertThrows,
@@ -36,6 +37,41 @@ Deno.test(function performanceToJSON() {
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() {
const mark = performance.mark("test");
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() {
assertStringIncludes(Deno.inspect(performance), "Performance");
assertStringIncludes(