There is an article where the author tries to compare performance of different web stacks. The result looks pretty controversial. I try to prove that in real use case the difference between scores of different stacks will be not so significant(under "real" I mean something which relies on database) .
For this purpose I take two stacks: one from the top side(node+express) and the looser(python+flask). And now I'm trying to implement a little bit more realistic use case for both platforms.
This is the code for the flask application:
#app.py
from flask import render_template
from flask import Flask
import sqlite3
conn = sqlite3.connect('data.db')
app = Flask(__name__)
c = conn.cursor()
if c.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='data'").fetchone() is None:
c.execute("CREATE TABLE data (value TEXT)")
conn.commit()
conn.close()
@app.route('/<int:number>')
def index(number=1):
conn = sqlite3.connect('data.db')
c = conn.cursor()
c.executemany("INSERT INTO data VALUES (?)", [(fib(number),)] * 10);
list = c.execute("select * from data limit 100").fetchall()
conn.commit()
conn.close()
return render_template('template.html', list=list)
def fib(n):
if n == 0: return 0
elif n == 1: return 1
else:
return fib(n - 1) + fib(n - 2)
if __name__ == '__main__':
app.run(debug=False)
#template.html
<ul>
{% for l in list %}
<li>{{ l[0] }}</li>
{% endfor %}
</ul>
And the code for node application:
// app.js
var express = require("express");
var jade = require('jade');
var db = new (require('sqlite3').verbose()).Database('data.db');
var app = express();
var fib = function (n) {
if (n === 0) {
return 0;
} else if (n == 1) {
return 1;
} else {
return fib(n - 1) + fib(n - 2)
}
};
var getApp = function () {
app.get("/:number", function (req, res) {
var number = req.param("number");
query = db.prepare("INSERT INTO data VALUES (?)")
for(var i=0; i<10; i++) {
query.run((fib(number)))
};
db.all("select * from data limit 100", function(err, rows){
var rendered = jade.renderFile('template.jade', {list: rows})
res.send(rendered);
});
});
app.listen(3000);
}
db.get(
"SELECT name FROM sqlite_master WHERE type='table' AND name='data'",
function (err, row) {
if(err !== null) {
throw new Error();
}
if(row === undefined) {
db.run('create table data (value text)', getApp)
} else {
getApp()
}
}
);
# template.jade
ul
each l in list
li=l.value
Questions
- Some advice about node code. How can I make it more idiomatic and beautiful?
- There is some strange behavior in the node app. Benchmark results proposed below should describe it. What I'm doing wrong?
I would be glad to achieve any piece of advice about improving these code samples.
Running 30s test @ http://localhost:3000/10 2 threads and 64 connections Thread Stats Avg Stdev Max +/- Stdev Latency 26.19s 4.89s 28.93s 77.14% Req/Sec 0.87 1.46 4.00 86.67% 64 requests in 30.01s, 81.25KB read Socket errors: connect 0, read 0, write 0, timeout 896
1 Answer 1
Since the Fibonacci algorithm is so nice and clean there is one little nitpicky thing to add. You don't need to directly return 0 and 1 in the base cases, you can just return n. So the function can be rewritten (in Javascript, my experience with Python is extremely subpar) as:
var fib = function(n) {
if(n === 0 || n === 1) {
return n;
}
return fib(n - 1) + fib(n - 2);
}
The algorithm is beautiful but it also does a lot of extraneous work when run in a loop, that can be removed with the technique of memoization (again, to keep these tests fair, I think (?) this is possible in Python as well but someone else could be of more use in helping with the code). In this specific case, the technique is incredibly easy to employ with a simple Javascript object as a cache
var fib = (function() {
var cache = {};
function fibonacci(n) {
if(n === 0 || n === 1) {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
return function(n) {
if(n in cache) {
return cache[n];
}
return fibonacci(n);
}
}());
-
\$\begingroup\$ Thanks, for the answer! In reality I use fibonacci algorithm just as simple computation and there is no reason to optimize this \$\endgroup\$kharandziuk– kharandziuk2014年09月07日 07:55:57 +00:00Commented Sep 7, 2014 at 7:55
Explore related questions
See similar questions with these tags.