Skip to content

Commit fb750d6

Browse files
meixgbengl
authored andcommitted
perf_hooks: use arrays to store EntryBuffers
Also order entries by startTime when calling getEntriesByType. Fix: #42004Fix: #42024 PR-URL: #42032Fixes: #42004Fixes: #42024 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
1 parent 48fa1e5 commit fb750d6

File tree

3 files changed

+59
-74
lines changed

3 files changed

+59
-74
lines changed

‎lib/internal/perf/observe.js‎

Lines changed: 24 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ const{
44
ArrayFrom,
55
ArrayIsArray,
66
ArrayPrototypeFilter,
7-
ArrayPrototypeFlatMap,
87
ArrayPrototypeIncludes,
98
ArrayPrototypePush,
109
ArrayPrototypePushApply,
1110
ArrayPrototypeSlice,
1211
ArrayPrototypeSort,
12+
ArrayPrototypeConcat,
1313
Error,
1414
ObjectDefineProperties,
1515
ObjectFreeze,
@@ -34,7 +34,6 @@ const{
3434
const{
3535
InternalPerformanceEntry,
3636
isPerformanceEntry,
37-
kBufferNext,
3837
}=require('internal/perf/performance_entry');
3938

4039
const{
@@ -89,8 +88,8 @@ const kSupportedEntryTypes = ObjectFreeze([
8988
]);
9089

9190
// Performance timeline entry Buffers
92-
constmarkEntryBuffer=createBuffer();
93-
constmeasureEntryBuffer=createBuffer();
91+
letmarkEntryBuffer=[];
92+
letmeasureEntryBuffer=[];
9493
constkMaxPerformanceEntryBuffers=1e6;
9594
constkClearPerformanceEntryBuffers=ObjectFreeze({
9695
'mark': 'performance.clearMarks',
@@ -154,9 +153,7 @@ function maybeIncrementObserverCount(type){
154153
classPerformanceObserverEntryList{
155154
constructor(entries){
156155
this[kBuffer]=ArrayPrototypeSort(entries,(first,second)=>{
157-
if(first.startTime<second.startTime)return-1;
158-
if(first.startTime>second.startTime)return1;
159-
return0;
156+
returnfirst.startTime-second.startTime;
160157
});
161158
}
162159

@@ -344,15 +341,8 @@ function enqueue(entry){
344341
return;
345342
}
346343

347-
constcount=buffer.count+1;
348-
buffer.count=count;
349-
if(count===1){
350-
buffer.head=entry;
351-
buffer.tail=entry;
352-
return;
353-
}
354-
buffer.tail[kBufferNext]=entry;
355-
buffer.tail=entry;
344+
ArrayPrototypePush(buffer,entry);
345+
constcount=buffer.length;
356346

357347
if(count>kMaxPerformanceEntryBuffers&&
358348
!kWarnedEntryTypes.has(entryType)){
@@ -372,63 +362,40 @@ function enqueue(entry){
372362
}
373363

374364
functionclearEntriesFromBuffer(type,name){
375-
letbuffer;
376-
if(type==='mark'){
377-
buffer=markEntryBuffer;
378-
}elseif(type==='measure'){
379-
buffer=measureEntryBuffer;
380-
}else{
381-
return;
382-
}
383-
if(name===undefined){
384-
resetBuffer(buffer);
365+
if(type!=='mark'&&type!=='measure'){
385366
return;
386367
}
387368

388-
lethead=null;
389-
lettail=null;
390-
letcount=0;
391-
for(letentry=buffer.head;entry!==null;entry=entry[kBufferNext]){
392-
if(entry.name!==name){
393-
head=head??entry;
394-
tail=entry;
395-
continue;
396-
}
397-
if(tail===null){
398-
continue;
399-
}
400-
tail[kBufferNext]=entry[kBufferNext];
401-
count++;
369+
if(type==='mark'){
370+
markEntryBuffer=name===undefined ?
371+
[] : ArrayPrototypeFilter(markEntryBuffer,(entry)=>entry.name!==name);
372+
}else{
373+
measureEntryBuffer=name===undefined ?
374+
[] : ArrayPrototypeFilter(measureEntryBuffer,(entry)=>entry.name!==name);
402375
}
403-
buffer.head=head;
404-
buffer.tail=tail;
405-
buffer.count=count;
406376
}
407377

408378
functionfilterBufferMapByNameAndType(name,type){
409379
letbufferList;
410380
if(type==='mark'){
411-
bufferList=[markEntryBuffer];
381+
bufferList=markEntryBuffer;
412382
}elseif(type==='measure'){
413-
bufferList=[measureEntryBuffer];
383+
bufferList=measureEntryBuffer;
414384
}elseif(type!==undefined){
415385
// Unrecognized type;
416386
return[];
417387
}else{
418-
bufferList=[markEntryBuffer,measureEntryBuffer];
388+
bufferList=ArrayPrototypeConcat(markEntryBuffer,measureEntryBuffer);
419389
}
420-
returnArrayPrototypeFlatMap(bufferList,
421-
(buffer)=>filterBufferByName(buffer,name));
422-
}
423-
424-
functionfilterBufferByName(buffer,name){
425-
constarr=[];
426-
for(letentry=buffer.head;entry!==null;entry=entry[kBufferNext]){
427-
if(name===undefined||entry.name===name){
428-
ArrayPrototypePush(arr,entry);
429-
}
390+
if(name!==undefined){
391+
bufferList=ArrayPrototypeFilter(bufferList,(buffer)=>buffer.name===name);
392+
}elseif(type!==undefined){
393+
bufferList=ArrayPrototypeSlice(bufferList);
430394
}
431-
returnarr;
395+
396+
returnArrayPrototypeSort(bufferList,(first,second)=>{
397+
returnfirst.startTime-second.startTime;
398+
});
432399
}
433400

434401
functionobserverCallback(name,type,startTime,duration,details){
@@ -476,20 +443,6 @@ function hasObserver(type){
476443
returnobserverCounts[observerType]>0;
477444
}
478445

479-
functioncreateBuffer(){
480-
return{
481-
head: null,
482-
tail: null,
483-
count: 0,
484-
};
485-
}
486-
487-
functionresetBuffer(buffer){
488-
buffer.head=null;
489-
buffer.tail=null;
490-
buffer.count=0;
491-
}
492-
493446
module.exports={
494447
PerformanceObserver,
495448
PerformanceObserverEntryList,

‎lib/internal/perf/performance_entry.js‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ const kType = Symbol('kType');
2222
constkStart=Symbol('kStart');
2323
constkDuration=Symbol('kDuration');
2424
constkDetail=Symbol('kDetail');
25-
constkBufferNext=Symbol('kBufferNext');
2625

2726
functionisPerformanceEntry(obj){
2827
returnobj?.[kName]!==undefined;
@@ -72,7 +71,6 @@ class InternalPerformanceEntry{
7271
this[kStart]=start;
7372
this[kDuration]=duration;
7473
this[kDetail]=detail;
75-
this[kBufferNext]=null;
7674
}
7775
}
7876

@@ -85,5 +83,4 @@ module.exports ={
8583
InternalPerformanceEntry,
8684
PerformanceEntry,
8785
isPerformanceEntry,
88-
kBufferNext,
8986
};
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// This file may needs to be updated to wpt:
2+
// https://github.com/web-platform-tests/wpt
3+
4+
import'../common/index.mjs';
5+
importassertfrom'assert';
6+
7+
import{performance}from'perf_hooks';
8+
import{setTimeout}from'timers/promises';
9+
10+
// Order by startTime
11+
performance.mark('one');
12+
awaitsetTimeout(50);
13+
performance.mark('two');
14+
awaitsetTimeout(50);
15+
performance.mark('three');
16+
awaitsetTimeout(50);
17+
performance.measure('three','three');
18+
awaitsetTimeout(50);
19+
performance.measure('two','two');
20+
awaitsetTimeout(50);
21+
performance.measure('one','one');
22+
constentries=performance.getEntriesByType('measure');
23+
assert.deepStrictEqual(entries.map((x)=>x.name),['one','two','three']);
24+
constallEntries=performance.getEntries();
25+
assert.deepStrictEqual(allEntries.map((x)=>x.name),['one','one','two','two','three','three']);
26+
27+
performance.mark('a');
28+
awaitsetTimeout(50);
29+
performance.measure('a','a');
30+
awaitsetTimeout(50);
31+
performance.mark('a');
32+
awaitsetTimeout(50);
33+
performance.measure('a','one');
34+
constentriesByName=performance.getEntriesByName('a');
35+
assert.deepStrictEqual(entriesByName.map((x)=>x.entryType),['measure','mark','measure','mark']);

0 commit comments

Comments
(0)