Skip to content

Commit 830574f

Browse files
mscdexaddaleax
authored andcommitted
events: improve arrayClone performance
PR-URL: #33774 Reviewed-By: Robert Nagy <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Zeyu Yang <[email protected]>
1 parent 1a09b4d commit 830574f

File tree

4 files changed

+36
-37
lines changed

4 files changed

+36
-37
lines changed

‎benchmark/events/ee-emit.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const bench = common.createBenchmark(main,{
1010

1111
functionmain({ n, argc, listeners }){
1212
constee=newEventEmitter();
13+
ee.setMaxListeners(listeners+1);
1314

1415
for(letk=0;k<listeners;k+=1)
1516
ee.on('dummy',()=>{});

‎benchmark/events/ee-listeners-many.js‎

Lines changed: 0 additions & 22 deletions
This file was deleted.

‎benchmark/events/ee-listeners.js‎

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,34 @@
22
constcommon=require('../common.js');
33
constEventEmitter=require('events').EventEmitter;
44

5-
constbench=common.createBenchmark(main,{n: [5e6]});
5+
constbench=common.createBenchmark(main,{
6+
n: [5e6],
7+
listeners: [5,50],
8+
raw: ['true','false']
9+
});
610

7-
functionmain({ n }){
11+
functionmain({ n, listeners, raw}){
812
constee=newEventEmitter();
13+
ee.setMaxListeners(listeners*2+1);
914

10-
for(letk=0;k<5;k+=1){
15+
for(letk=0;k<listeners;k+=1){
1116
ee.on('dummy0',()=>{});
1217
ee.on('dummy1',()=>{});
1318
}
1419

15-
bench.start();
16-
for(leti=0;i<n;i+=1){
17-
constdummy=(i%2===0) ? 'dummy0' : 'dummy1';
18-
ee.listeners(dummy);
20+
if(raw==='true'){
21+
bench.start();
22+
for(leti=0;i<n;i+=1){
23+
constdummy=(i%2===0) ? 'dummy0' : 'dummy1';
24+
ee.rawListeners(dummy);
25+
}
26+
bench.end(n);
27+
}else{
28+
bench.start();
29+
for(leti=0;i<n;i+=1){
30+
constdummy=(i%2===0) ? 'dummy0' : 'dummy1';
31+
ee.listeners(dummy);
32+
}
33+
bench.end(n);
1934
}
20-
bench.end(n);
2135
}

‎lib/events.js‎

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ EventEmitter.prototype.emit = function emit(type, ...args){
322322
}
323323
}else{
324324
constlen=handler.length;
325-
constlisteners=arrayClone(handler,len);
325+
constlisteners=arrayClone(handler);
326326
for(leti=0;i<len;++i){
327327
constresult=ReflectApply(listeners[i],this,args);
328328

@@ -563,7 +563,7 @@ function _listeners(target, type, unwrap){
563563
returnunwrap ? [evlistener.listener||evlistener] : [evlistener];
564564

565565
returnunwrap ?
566-
unwrapListeners(evlistener) : arrayClone(evlistener,evlistener.length);
566+
unwrapListeners(evlistener) : arrayClone(evlistener);
567567
}
568568

569569
EventEmitter.prototype.listeners=functionlisteners(type){
@@ -602,11 +602,17 @@ EventEmitter.prototype.eventNames = function eventNames(){
602602
returnthis._eventsCount>0 ? ReflectOwnKeys(this._events) : [];
603603
};
604604

605-
functionarrayClone(arr,n){
606-
constcopy=newArray(n);
607-
for(leti=0;i<n;++i)
608-
copy[i]=arr[i];
609-
returncopy;
605+
functionarrayClone(arr){
606+
// At least since V8 8.3, this implementation is faster than the previous
607+
// which always used a simple for-loop
608+
switch(arr.length){
609+
case2: return[arr[0],arr[1]];
610+
case3: return[arr[0],arr[1],arr[2]];
611+
case4: return[arr[0],arr[1],arr[2],arr[3]];
612+
case5: return[arr[0],arr[1],arr[2],arr[3],arr[4]];
613+
case6: return[arr[0],arr[1],arr[2],arr[3],arr[4],arr[5]];
614+
}
615+
returnarr.slice();
610616
}
611617

612618
functionunwrapListeners(arr){

0 commit comments

Comments
(0)