continuation.js
Advanced tools
Comparing version 0.2.0 to 0.2.1
{ | ||
"name": "continuation.js", | ||
"description": "A module for tail call optimization by Continuation Passing Style (CPS) transformation with trampoline technique for Node.js", | ||
"version": "0.2.0", | ||
"version": "0.2.1", | ||
"author": "Daishi Kato <daishi@axlight.com>", | ||
@@ -6,0 +6,0 @@ "dependencies": { |
179
README.md
@@ -10,3 +10,4 @@ continuation.js | ||
Node.js is often used with callback functions, | ||
which tend to be tail calls (but not necessarily recursions). | ||
which tend to be tail calls (but not necessarily recursions) | ||
consuming call stacks. | ||
@@ -16,3 +17,3 @@ This module allows to transform native JavaScript code into | ||
It utilizes so-called trampoline technique to avoid a stack overflow error. | ||
Transforming all function into CPS is not very easy | ||
Transforming all functions into CPS is not very easy | ||
(and sometimes not very efficient), | ||
@@ -30,14 +31,45 @@ hence it has a fallback mechanism, that is, only supported | ||
| NAME | continuation.js | [Brushtail][1] | [tailrec.js][2] | [thunk.js][3] | [tail-call][4] | | ||
|-------------------------|-----------------|----------------|-----------------|---------------|----------------| | ||
| Tail Call Optimization | Yes | Yes | Yes | Yes | Yes | | ||
| Mutual TCO | Yes | No | Yes | No | No | | ||
| Native JavaScript | Yes | Yes | No | No | Almost | | ||
| `require()` integration | Yes | No | No | No | No | | ||
<table> | ||
<tr> | ||
<th>NAME</th> | ||
<th>continuation.js</th> | ||
<th><a href="https://github.com/pufuwozu/brushtail">Brushtail</a></th> | ||
<th><a href="https://github.com/natefaubion/tailrec.js">tailrec.js</a></th> | ||
<th><a href="https://github.com/jayferd/thunk.js">thunk.js</a></th> | ||
<th><a href="https://github.com/Gozala/js-tail-call">tail-call</a></th> | ||
</tr> | ||
<tr> | ||
<td>Tail call optimization</td> | ||
<td>Yes</td> | ||
<td>Yes</td> | ||
<td>Yes</td> | ||
<td>Yes</td> | ||
<td>Yes</td> | ||
</tr> | ||
<tr> | ||
<td>Mutual recursion</td> | ||
<td>Yes</td> | ||
<td>No</td> | ||
<td>Yes</td> | ||
<td>No</td> | ||
<td>No</td> | ||
</tr> | ||
<tr> | ||
<td>Native JavaScript</td> | ||
<td>Yes</td> | ||
<td>Yes</td> | ||
<td>No</td> | ||
<td>No</td> | ||
<td>Almost</td> | ||
</tr> | ||
<tr> | ||
<td>`require()` integration</td> | ||
<td>Yes</td> | ||
<td>No</td> | ||
<td>No</td> | ||
<td>No</td> | ||
<td>No</td> | ||
</tr> | ||
</table> | ||
[1]: https://github.com/pufuwozu/brushtail "pufuwozu/brushtail" | ||
[2]: https://github.com/natefaubion/tailrec.js "natefaubion/tailrec.js" | ||
[3]: https://github.com/jayferd/thunk.js "jayferd/thunk.js" | ||
[4]: https://github.com/Gozala/js-tail-call "Gozala/js-tail-call" | ||
How to use | ||
@@ -139,20 +171,106 @@ ---------- | ||
| Suite name | Original | CPS transformed | Improved? | | ||
|-----------------|---------------|-----------------|-----------| | ||
| Richards | 324 ops/sec | 38.28 ops/sec | No | | ||
| DeltaBlue | 188 ops/sec | 12.90 ops/sec | No | | ||
| Encrypt | 162 ops/sec | 122 ops/sec | No | | ||
| Decrypt | 8.62 ops/sec | 6.86 ops/sec | No | | ||
| RayTrace | 19.71 ops/sec | 4.10 ops/sec | No | | ||
| Earley | 278 ops/sec | 33.91 ops/sec | No | | ||
| Boyer | 18.19 ops/sec | 1.60 ops/sec | No | | ||
| RegExp | 7.12 ops/sec | 5.14 ops/sec | No | | ||
| Splay | 123 ops/sec | 75.21 ops/sec | No | | ||
| NavierStokes | 2.40 ops/sec | 3.13 ops/sec | Yes | | ||
| PdfJS | 2.85 ops/sec | 2.68 ops/sec | No | | ||
| Gameboy | 0.98 ops/sec | 0.35 ops/sec | No | | ||
| CodeLoadClosure | 370 ops/sec | 372 ops/sec | Yes | | ||
| CodeLoadJQuery | 8.83 ops/sec | 10.61 ops/sec | Yes | | ||
| Box2D | 2.33 ops/sec | 2.54 ops/sec | Yes | | ||
<table> | ||
<tr> | ||
<th>Suite name</th> | ||
<th>Original</th> | ||
<th>CPS transformed</th> | ||
<th>Improved?</th> | ||
</tr> | ||
<tr> | ||
<td>Richards</td> | ||
<td>324 ops/sec</td> | ||
<td>38.28 ops/sec</td> | ||
<td>No</td> | ||
</tr> | ||
<tr> | ||
<td>DeltaBlue</td> | ||
<td>188 ops/sec</td> | ||
<td>12.90 ops/sec</td> | ||
<td>No</td> | ||
</tr> | ||
<tr> | ||
<td>Encrypt</td> | ||
<td>162 ops/sec</td> | ||
<td>122 ops/sec</td> | ||
<td>No</td> | ||
</tr> | ||
<tr> | ||
<td>Decrypt</td> | ||
<td>8.62 ops/sec</td> | ||
<td>6.86 ops/sec</td> | ||
<td>No</td> | ||
</tr> | ||
<tr> | ||
<td>RayTrace</td> | ||
<td>19.71 ops/sec</td> | ||
<td>4.10 ops/sec</td> | ||
<td>No</td> | ||
</tr> | ||
<tr> | ||
<td>Earley</td> | ||
<td>278 ops/sec</td> | ||
<td>33.91 ops/sec</td> | ||
<td>No</td> | ||
</tr> | ||
<tr> | ||
<td>Boyer</td> | ||
<td>18.19 ops/sec</td> | ||
<td>1.60 ops/sec</td> | ||
<td>No</td> | ||
</tr> | ||
<tr> | ||
<td>RegExp</td> | ||
<td>7.12 ops/sec</td> | ||
<td>5.14 ops/sec</td> | ||
<td>No</td> | ||
</tr> | ||
<tr> | ||
<td>Splay</td> | ||
<td>123 ops/sec</td> | ||
<td>75.21 ops/sec</td> | ||
<td>No</td> | ||
</tr> | ||
<tr> | ||
<td>NavierStokes</td> | ||
<td>2.40 ops/sec</td> | ||
<td>3.13 ops/sec</td> | ||
<td>Yes</td> | ||
</tr> | ||
<tr> | ||
<td>PdfJS</td> | ||
<td>2.85 ops/sec</td> | ||
<td>2.68 ops/sec</td> | ||
<td>No</td> | ||
</tr> | ||
<tr> | ||
<td>Gameboy</td> | ||
<td>0.98 ops/sec</td> | ||
<td>0.35 ops/sec</td> | ||
<td>No</td> | ||
</tr> | ||
<tr> | ||
<td>CodeLoadClosure</td> | ||
<td>370 ops/sec</td> | ||
<td>372 ops/sec</td> | ||
<td>Yes</td> | ||
</tr> | ||
<tr> | ||
<td>CodeLoadJQuery</td> | ||
<td>8.83 ops/sec</td> | ||
<td>10.61 ops/sec</td> | ||
<td>Yes</td> | ||
</tr> | ||
<tr> | ||
<td>Box2D</td> | ||
<td>2.33 ops/sec</td> | ||
<td>2.54 ops/sec</td> | ||
<td>Yes</td> | ||
</tr> | ||
</table> | ||
Since trampoline is costly, | ||
performance drops in most suites especially basic ones. | ||
Whereas in relatively complex suites, there are some cases | ||
when performance is improved. (Anybody interested why this is happening?) | ||
Limitations | ||
@@ -168,4 +286,3 @@ ----------- | ||
* Transform all tail recursive calls into CPS. | ||
* Work with try...catch and throw. | ||
* Transform non-tail recursive calls into CPS. |
162516
284