Skip to content

Instantly share code, notes, and snippets.

@karanlyons
Created June 4, 2012 14:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save karanlyons/2868852 to your computer and use it in GitHub Desktop.
Save karanlyons/2868852 to your computer and use it in GitHub Desktop.
Node vs. Gevent (Sync and Async)
#!/usr/bin/env python
# encoding: utf-8
# $ brew install libev
# $ pip install http://gevent.googlecode.com/files/gevent-1.0b2.tar.gz
# $ chmod +x ./gevent_fib.py
# $ ./gevent_fib.py
import time
from gevent.pywsgi import WSGIServer
from gevent import monkey
monkey.patch_all()
def syncfib(n): # Six lines, one named function.
if n < 2:
return n
else:
return syncfib(n - 2) + syncfib(n - 1)
def asyncfib(n): # Eight lines, one named function, one call to `time.sleep()` (patched to `gevent.sleep()`).
if n < 2:
return n
else:
time.sleep() # Explicitely yielding (canonically `gevent.sleep()`, but with monkey-patching it's the same; perhaps slightly slower for the extra reference.).
return asyncfib(n - 2) + asyncfib(n - 1)
def wait(n): # Again, for testing...also four lines.
time.sleep(n) # `monkey.patch_all()` made this non-blocking. More accurately, it now blocks the greenlet running this code instead of the entire interpreter.
return n
def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
path = environ['PATH_INFO']
version = path[1:2]
try:
n = int(path[3:])
except ValueError:
n = 25
if version == 's': # Sync
return ["Sync: %i" % syncfib(n)]
elif version == 'a': # Async
return ["Async: %i" % asyncfib(n)]
elif version == 'w': # Wait
return ["Slept: %i second%s." % (wait(n), 's' if n != 1 else '')]
else:
return ["Try:<br /><a href='http://localhost:8000/s/25'>sync</a><br /><a href='http://localhost:8000/a/25'>async</a><br /><a href='http://localhost:8000/w/25'>wait</a>"]
if __name__ == '__main__':
app = WSGIServer(('', 8000), application, log=None)
print "Serving on http://127.0.0.1:8000/."
try:
app.serve_forever()
except KeyboardInterrupt:
app.stop()
#!/usr/bin/env node
// $ brew install node
// $ curl http://npmjs.org/install.sh | sh
// $ npm install async
// $ chmod +x ./node_fib
// $ ./node_fib
var http = require('http');
var url = require('url');
var async = require('async');
var syncfib = function (n) { // Nine lines, one named function.
if (n < 2) {
return n;
}
else {
return syncfib(n - 2) + syncfib(n - 1);
}
}
var asyncfib = function (n, callback) { // 14 lines, one named function, three anonymous functions. Two calls to `process.nextTick()` inside of functions.
if (n < 2) { // Node conventions: 1st arg is usually an error/null, last arg is a callback (if required).
callback(null, n);
}
else {
async.series([
function (callback) { process.nextTick(function() { asyncfib(n - 2, callback); }); }, // Without `process.nexTick()` you'll hit the call stack limit very quickly.
function (callback) { process.nextTick(function() { asyncfib(n - 1, callback); }); }
], function (error, results) {
callback(null, results[0] + results[1]);
});
}
}
var wait = function (n, callback) { // Just for testing...and two lines.
setTimeout(callback, n * 1000);
}
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/html'});
var path = url.parse(request.url, true).pathname;
var version = path.slice(1,2);
var n = parseInt(path.slice(3)) || 25;
switch (version) {
case 's': // Sync
response.end("Sync: " + syncfib(n));
break;
case 'a': // Async
asyncfib(n, function (error, results) { response.end("Async: " + results); });
break;
case 'w': // Wait
wait(n, function () { response.end("Slept: " + n + " second" + (n != 1 ? "s" : "") + "."); });
break;
default: // Some helpful links
response.end("Try:<br /><a href='http://localhost:8000/s/25'>sync</a><br /><a href='http://localhost:8000/a/25'>async</a><br /><a href='http://localhost:8000/w/25'>wait</a>");
break;
}
}).listen(8000);
console.log("Serving on http://127.0.0.1:8000/.");
@karanlyons
Copy link
Author

I've probably done something wrong here and so unfairly favored one side or the other. But I've done my best not to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment