I have developed `[Aigle](https://github.com/suguru03/aigle)` which is a fast Promise library. It is inspired by`[Bluebir](https://github.com/petkaantonov/bluebird)d`. The library is not only a [benchmark](https://github.com/suguru03/aigle/tree/master/benchmark#benchmark) exercise but a production-ready library that implements the Promise A+ standard, and does so faster than `Bluebird`. ### **What are Promises?** Before explaining it, I would like to give basic information about Promises. A Promise can have three states: `pending`, `fulfilled` and `rejected`. Once the state goes to another state from `pending`, the state cannot change again. Besides, Promises must always resolve asynchronously, this is one of the most important things. **new** Promise(resolve => resolve(1)) // synchronously .then(num => { // called asynchronously }); ### Best practices for high-performance libraries When I develop libraries, I always follow these three principles. * Avoid creating unnecessary variables, functions and instances * Avoid executing unnecessary functions * Deal with asynchronous function smartly #### Avoid creating unnecessary variables, functions and instances Following this principle helps avoiding unnecessary memory allocations. For example, **function** sum(array) { **return** array.reduce(**function** iterator(result, num) { **return** result **+** num; }); } sum(\[1, 2, 3\]); _// 6_ When `sum` is called, the `iterator` function is always created. It is one of unnecessary memory allocations. The code is rewritten to follow next example. **function** iterator(result, num) { **return** result **+** num; } **function** sum(array) { **return** array.reduce(iterator); } sum(\[1, 2, 3\]); _// 6_ The code avoids making unnecessary functions. Next is another extra example of memory allocation. **function** get(type) { **const** array **\=** \[\]; **const** object **\=** {}; **const** number **\=** 0; **const** string **\=** ''; **switch** (type) { **case** 'array'**:** **return** array; **case** 'object'**:** **return** object; **case** 'number'**:** **return** number; **case** 'string'**:** **return** string; } } get('string'); In this case, `string` is the only required variable. `array`, `object` and `number` are unnecessary. The code is rewritten as below, **function** get(type) { **switch** (type) { **case** 'array'**:** **return** \[\]; **case** 'object'**:** **return** {}; **case** 'number'**:** **return** 0; **case** 'string'**:** **return** ''; } } get('string'); There is not a big difference between the examples, but if instances or functions are created in the function, it would make big difference. #### Avoid executing unnecessary functions For example, when creating APIs, it is necessary to check the request parameters. **function** api(req, res) { **const** { id } **\=** req.body; **if** (**!**isNumber(id)) { **return** res.sendStatus(400); } innerFunc(id) .then(...) .**catch**(...) } **function** isNumber(id) { **return** **typeof** id **\===** 'number'; } **function** innerFunc(id) { **if** (**!**isNumber(id)) { **return** Promise.reject(**new** Error('error')); } ... } When implementing APIs, it is preferable to check the arguments in inner functions because the function might be called from other functions. However, when implementing libraries, the function doesn’t need to check the arguments. Before executing inner functions, the arguments are already checked, so it isn’t necessary to check them again in inner functions. #### Deal with asynchronous function smartly I would like to explain this concept with `Bluebird` examples. ### What makes `Bluebird fast?` If you open `Bluebird` library code, you will see `bitField` parameters. But the `bitField` is not so important. `Bluebird` has roughly two states: `pending` or not. The big difference in handling is between the two states. #### If the state is pending: **new** Bluebird(**function** executor(resolve) { // called synchronously setTimeout(**function** timer() { resolve(1); _// called asynchronously_ }, 10); }) .then(**function** onFulfilled(value) { _// called asynchronously_ }); This execution order is, 1. Make a parent instance of `Bluebird` when new `Bluebird` is called 2. Execute `executor` 3. Execute `then`.`then` makes a child instance of `Bluebird` 4. Execute `resolve` 5. Execute `onFulfilled` When `then` is called, [a child instance is created](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/promise.js#L228). At that time, `resolve` is not called yet, so the parent’s state is `pending`. When the state is `pending`, [the child instance is linked to the parent instance as a child](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/promise.js#L416). After that, `[resolve](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/promise.js#L513)` [is called](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/promise.js#L513) asynchronously by `setTimeout`. And then, `[onFulfilled](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/promise.js#L703-L710)` [is called with the result](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/promise.js#L703-L710). When state is `pending`, a child instance is linked to parent instance. After `resolve` is called, `onFulfilled` is called. It is very simple. #### If state is not pending: **new** Bluebird(**function** executor(resolve) { resolve(); _// called synchronously_ }) .then(**function** onFulfilled(value) { _// ensured asynchronously_ }); The execution order is 1. Make a parent instance of `Bluebird` when new `Bluebird` is called 2. Execute `executor` 3. Execute `resolve` 4. Execute `then`. `then` makes a child instance of `Bluebird` 5. Execute `onFulfilled` When `then` is called, the parent’s state is already not `pending`. In this case, if `onFulfilled` is called without anything, the function is executed synchronously. For that reason, the library needs to [call an asynchronous function](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/promise.js#L263-L270). Before calling the function, `onFulfilled` is [set to](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/async.js#L88) a `[queue](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/async.js#L88)` and this `[schedule](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/async.js#L159)` [function is called](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/async.js#L159). The `schedule` is `setImmediate` on Node.js. And then `[setImmediate](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/async.js#L144)` [calls all queued functions asynchronously](https://github.com/petkaantonov/bluebird/blob/v3.4.7/src/async.js#L144). When a state is not `pending`, `onFulfilled` is set to a `queue`, and then queued functions are executed by asynchronous functions. You might be wondering why `onFulfilled` is set to a `queue`. This is the smartest idea in `Bluebird`. #### How to handle the asynchronous function smartly I would like to explain it with this example. Bluebird.resolve(1) _// synchronously_ .then(num **\=>** console.log(num)); _// asynchronously_ Bluebird.resolve(2) _// synchronously_ .then(num **\=>** console.log(num)); _// asynchronously_ Bluebird.resolve(3) _// synchronously_ .then(num **\=>** console.log(num)); _// asynchronously_ If a `queue` is not used, an asynchronous function is called three times. But if a `queue` is used, the function executes all queued functions at once. I’m not sure if the `bitField` gives a big benefit or not. But I think why `Bluebird` is fast is because of simplicity. ### What makes Aigle fast? I have just followed these important principles, * Avoid creating unnecessary variables, functions and instances * Avoid executing unnecessary functions * Deal with asynchronous function smartly If you follow them, you will be able to make good libraries. I made a [benchmark](https://github.com/suguru03/aigle/tree/master/benchmark#benchmark) to check performance between `Aigle` and `Bluebird`. The benchmark result is here. * Node v6.9.1 * Aigle v0.5.0 * Bluebird v3.5.0  Aigle vs Bluebird `Aigle` has very simple implementation, therefore it is faster than `Bluebird`. If you are interested in `Aigle`, I would like you to contribute to it. #### Intended for production environment The most important part is`aigle-core` dependency. In `Bluebird`, every promise instance has to be an instance of `Bluebird`. When the instance is checked, `instanceof` function is called. But `Bluebird` only checks if the instance is made by the **current** `**Bluebird**` class or not. So if many versions are used, `Bluebird` will be slowed down. The key to avoiding losing performance is to have same dependency. `Aigle` has `aigle-core` dependency, therefore every `Aigle` instance is extended by same `AigleCore` class. `Aigle` will keep high performance. I would like to show [the benchmark example](https://github.com/suguru03/aigle-benchmark). $ npm list aigle-benchmark@0.0.0 ├─┬ aigle@0.5.0 <- aigle@0.5.0 has aigle-core@0.2.0 │ └── aigle-core@0.2.0 ├─┬ benchmark@2.1.3 │ └── platform@1.3.3 ├── bluebird@3.5.0 ├── lodash@4.17.4 ├── minimist@1.2.0 └─┬ promise-libraries@0.3.0 ├── aigle@0.4.0 <- aigle@0.4.0 has aigle-core@0.2.0 too └── bluebird@3.4.6 As you can see, different `aigle` dependencies have same `aigle-core` sub-dependencies. When `aigle@0.4.0` is used, the `aigle-core` is shared. * Node v6.9.1 * `Aigle` v0.4.0, v0.5.0 * `Bluebird` v3.4.6, v3.5.0 $ node --expose_gc . -t then======================================[Aigle] v0.5.0[Bluebird] v3.5.0======================================[promise:then:same] Preparing...--------------------------------------[promise:then:same] Executing...[1] "aigle" 180μs[1.00][1.00][2] "bluebird" 341μs[0.526][1.90]======================================[promise:then:diff] Preparing...--------------------------------------[promise:then:diff] Executing...[1] "aigle" 178μs[1.00][1.00][2] "bluebird" 506μs[0.352][2.84] `promise:then:same` was using same versions, and `promise:then:diff` used child instances of different versions. `Aigle` never slows down even if the versions are mixed. ### Conclusion If you follow the three important principles, you will make a fast library. Also `Aigle` has many functions inspired by `[Async](https://github.com/caolan/async)` and `[Neo-Async](https://github.com/suguru03/neo-async)`. If you still use callback style, I would like to encourage you using `Aigle`. If I contribute to `Node.js` and `JavaScript` communities, I would be happy as a contributor. ### Reference * `[Aigle](https://github.com/suguru03/aigle)` * `[Bluebird](https://github.com/petkaantonov/bluebird)` * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)