-
-
Save bjouhier/2362015 to your computer and use it in GitHub Desktop.
"use strict"; | |
var fs = require('fs'); | |
var cache = {}, hit = 0, missed = 0; | |
function load(name, cb) { | |
var res = cache[name]; | |
if (res) { | |
process.nextTick(function() { | |
hit++; | |
cb(null, res); | |
}); | |
} else { | |
fs.readFile(name, function(err, data) { | |
missed++; | |
cb(null, cache[name] = data); | |
}); | |
} | |
} | |
var count = 1000000; | |
function bench(cb) { | |
var total = 0; | |
function loop(i) { | |
if (i === count) { | |
cb(null, total); | |
} else { | |
load(__dirname + '/benchCallbacks.js', function(err, data) { | |
if (err) return cb(err); | |
total += data.length; | |
loop(i + 1); | |
}) | |
} | |
} | |
loop(0); | |
} | |
var t0 = Date.now(); | |
bench(function(err, result) { | |
if (err) throw err; | |
console.log('hit=' + hit + ', missed=' + missed + ', result=' + result); | |
console.log('elapsed: ' + (Date.now() - t0)); | |
}); |
"use strict"; | |
var fs = require('fs'); | |
var cache = {}, hit = 0, missed = 0; | |
function load(name, _) { | |
var res = cache[name]; | |
if (res) { | |
hit++; | |
return res; | |
} else { | |
missed++; | |
return cache[name] = fs.readFile(name, _); | |
} | |
} | |
var count = 1000000; | |
function bench(_) { | |
var total = 0; | |
for (var i = 0; i < count; i++) { | |
var res = load(__dirname + '/benchCallbacks.js', _); | |
total += res.length; | |
} | |
return total; | |
} | |
var t0 = Date.now(); | |
var result = bench(_); | |
console.log('hit=' + hit + ', missed=' + missed + ', result=' + result); | |
console.log('elapsed: ' + (Date.now() - t0)); |
What Bruno is doing is important because one should not write callback-style code in every case. Business logic for example or you are setting yourself up to a maintenance nightmare. Library code is fine because that's the hard core Node guys are accustomed to. :-)
I work currently at a (non-Node) project where the son of the boss knows a little programming. This is very helpful for the project because this makes communication a lot easier: he functions as a relay between the company and software development. But I cannot imagine that he could write or understand business logic in callback-style. I definitively would use Streamline in such a case!
The million times in a row is just one of the corner cases: Javascript does not do tail calls. creationix already mentioned that he used a trampoline, that means, the Node hard core guys already know a lot about these corner cases.
I have a plea to the Node community: Please pay more respect to Bruno! I think what he does is saving Node in the long term from fading away into a niche for really clever programmers.
Thanks Nalply.
Just published a follow-up post on my blog: http://bjouhier.wordpress.com/2012/04/14/node-js-awesome-runtime-and-new-age-javascript-gospel/
As a side note, could it be that the fiber version runs faster because async calls are so much more expensive than sync ones?
See http://jsperf.com/asynch-cost
Surprised? well... you now understand better my "node anxiety" issue -- http://news.ycombinator.com/item?id=2371152
When was the last time you had to load the same thing a million times in a row in a tight loop?
I can't figure out what program this benchmark is supposed to represent.