From f6a28993619ac23d6e1a8d5d3cc81a308a652b83 Mon Sep 17 00:00:00 2001 From: Carles Escrig Royo Date: Fri, 20 Sep 2024 21:03:13 +0200 Subject: [PATCH] perf(ext/web): optimize performance.measure() Optimizes the case when `performance.measure()` needs to find the startMark by name, by avoiding copying and reversing the complete entries list. --- ext/web/15_performance.js | 13 ++++---- tests/unit/performance_test.ts | 55 ++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/ext/web/15_performance.js b/ext/web/15_performance.js index 5045c0d318fdf1..ea5557278138fa 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 93af641ad8e452..fa056c7f545301 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(