-
Notifications
You must be signed in to change notification settings - Fork 56
Fast mode
The fast mode allows streamline to generate leaner and faster code but it requires a few more keystrokes and a bit of extra care when writing the code.
The fast mode is designed to optimize function calls between streamlined functions: one streamlined function calling another streamlined function. To enable this you need to tell the compiler if you are calling a streamlined function or a normal callback-based function so that it can optimize the streamline-to-streamline case. This is achieved with small variations on the original syntax.
To call a streamlined function from another streamlined function, just use the usual _
syntax:
var result = f(_);
To call a normal callback-based function, just replace _
by ~_
. For example:
var stat = require('fs').stat(filename, ~_);
You can also convert a callback-based function into a function that you can then call with _
. You can do this with _(fn, idx)
where fn
is the callback-based function and idx
is the index of the callback in its parameter list:
var mystat = _(require('fs').stat, 1);
var stat = mystat(filename, _); // no ~ here!
Note that this syntax does not work too well with functions that have optional parameters before the _
. The idx
value must match the _
that you will be passing in your calls.
The mix of _
and ~_
can be annoying and error prone. You can avoid this by writing wrappers around callback APIs. Streamline comes with several companion packages:
-
streamline-fs
: a wrapper around node'sfs
module. -
streamline-streams
: a wrapper for streams (which also gives you a simpler API) -
streamline-mongodb
: wrapper classes for themongodb
package.
The previous stat
example can be rewritten as:
var stat = require('streamline-fs').stat(filename, _);
Note: streamline-fs
fixes the odd callback signature of fs.exists
.
The fast mode also requires a syntax element to distinguish calls that create futures from other calls. Instead of omitting the _
parameter or passing null
you have to pass !_
(think of it as not wait). For example:
var statFuture = require('streamline-fs').stat(filename, !_);
// ...
var stat = statFuture(_);
When you use streamline in fast mode your streamlined functions are not transformed into regular async functions with the usual node.js callback signature. So you cannot call them directly with a callback; you have to use the special _ >> callback
syntax.
For example, in non-fast mode, you can write:
function f(_) { ... }
f(function(err, result) {
// ...
});
In fast mode, you have to write:
function f(_) { ... }
f(_ >> function(err, result) {
// ...
});
Think of >>
as meaning leaving streamline-fast.
As streamlined functions are not transformed into regular async functions you cannot call them directly from event handlers either; you need a special syntax: _ << function(_) { ... }
For example, in non-fast mode you can write (see FAQ):
server.on('eventA', function(arg, _) {
// function has an _ parameter, you can use streamline
}).on('eventB', function(arg, _) {
// streamline code
});
In fast mode, you would write this as:
server.on('eventA', _ << function(arg, _) {
// function has an _ parameter, you can use streamline
}).on('eventB', _ << function(arg, _) {
// streamline code
});
Think of <<
as meaning entering streamline-fast.
The fast mode does not impact streamline-to-streamline calls, except for futures but it impacts boundary calls:
- streamlined functions calling callback-based functions
- event or callback-based code calling streamlined functions.
The following table gives a summary of the fast syntax:
result = f(_); | streamline calling streamlined function f |
result = f(~_); | streamline calling callback-based function f |
future = f(!_); | calling streamlined function f as a future |
_(f, idx) | converts a callback-based function f to a streamlined function |
f(_ >> cb); | calling streamlined function f with a regular callback cb |
emitter.on('event', _ << function(arg, _) { ... } | registering a streamlined function as an event handler |
The fast mode produces faster code in fibers and generators but it does not have any impact in callbacks mode. It would be possible to take advantage of the additional directives to generate more efficient code in this case too but this has not yet been implemented.
The fast syntax is accepted in non-fast mode. It is just ignored. This is useful if you are upgrading existing code to take advantage of the fast mode. It is likely that you won't get all the directives right the first time. But they won't break your code. So you can turn the fast
option on to test the fast mode and still keep working code in non-fast mode.