-
Notifications
You must be signed in to change notification settings - Fork 12
A brief history of mini signals
Sometime earlier this year I needed an event emitter for a browser-based game engine. After examining a few choices, I settled on js-signals. The signals API was much better suited for a game engine then your typical JavaScript event emitter. After some time, I realized that js-signals had a minor design flaw that caused the v8 engine (the core of chrome and node) to deoptimize the dispatch
method. In most uses of js-signals, the impact is negligible, but for something like a game engine that could be dispatching events at rates of 60 per second, it was noticeable.
After examining js-signals and other event emitters in depth I began to develop mini-signals. mini-signals v0.0.1 was partially API compatible the js-signals API, fixed the deoptimization issue, and implemented some optimization technique I saw in the very fast EventEmitter3. In fact, v0.0.1 was a fork of EventEmitter3. I proudly declared that mini-signals had dispatch speed was on par with EventEmitter3.
I eventually realized that the way EventEmitter3 was getting this speed boost was using something like a linked list when the number of listeners was less than two (i.e. zero or one) then switching to Array after two listeners were added. I experimented with doubly linked list in mini-signals and saw a near 7x improvement in mini-signals performance vs EventEmiiter3. The speed boost was due to the combination of linked lists and preventing the v8 deoptimization I discussed, something that is not possible in event emitters that use strings for event types. v0.0.2 of mini-signals implemented doubly linked lists.
So why didn’t EventEmitter3 (and js-signals for that matter) use a linked list? Because other API methods such as add
and remove
, which both required an O(n) search in the js-signals implementation, would be slower with a linked list. As I continued to work on mini-signals (releasing a few versions and switching to an ES6 implementation) I realized that by implementing some of @millermedeiros ideas for a potential js-signals 2.0 API I could make both add
and remove
operations O(1). mini-signals v1.0 was released with the old API deprecated and the new faster API in place.
To be continued...