Run details:
Mozilla/5.0 (X11; Linux x86_64; rv:105.0) Gecko/20100101 Firefox/105.0
Firefox 105
Linux
Desktop
2 years ago
Test name Executions per second
loop observable 66.0 Ops/sec
EventTarget observable 51.3 Ops/sec
ExtendedEvent observable 50.1 Ops/sec
Script Preparation code:
x
 
function LoopObservable() {
    const listeners = new Set();
    this.on = fn => listeners.add(fn);
    this.off = fn => listeners.delete(fn);
    this.clear = () => listeners.clear();
    
    // This has bad failure modes.
    this.send = function(...message) {
        for (let fn of listeners)
            fn(...message);
    };
};
function EventTargetObservable() {
    // Name is arbitrary because we're using a dedicated object.  Use a shorter
    // name for shorter lookup.
    const NAME = '.';
    const __ = document.createTextNode(null);
    
    this.on = function(handler) {
        __.addEventListener(NAME, event => {
            handler(event.detail);
        });
    };
    
    this.off = function(handler) {
        __.removeEventListener(NAME, handler);
    };
    
    this.send = function(detail) {
        __.dispatchEvent(new CustomEvent(NAME, {detail}));
    };
}
class ExtendedEvent extends Event {
    constructor(name, data){
      super(name);
      this.D = data;
    }
  
  
}
function ExtendedEventTargetObservable() {
    // Name is arbitrary because we're using a dedicated object.  Use a shorter
    // name for shorter lookup.
    const NAME = '.';
    const __ = document.createTextNode(null);
    
    this.on = function(handler) {
        __.addEventListener(NAME, event => {
            handler(event.D);
        });
    };
    
    this.off = function(handler) {
        __.removeEventListener(NAME, handler);
    };
    
    this.send = function(data) {
        __.dispatchEvent(new ExtendedEvent(NAME, data));
    };
}
function run_test(observable, handlers = 2, calls = 1000) {
    for (let i = 0; i < handlers; i++)
        observable.on(message => console.log(i, message));
    
    for (let i = 0; i < calls; i++)
        observable.send({type: "hello", i});
}
Tests:
  • loop observable

     
    run_test(new LoopObservable());
  • EventTarget observable

     
    run_test(new EventTargetObservable());
  • ExtendedEvent observable

     
    run_test(new ExtendedEventTargetObservable());