对同一个平凡方法的第二个HTTP调用要慢得多



代码很简单:

const express = require('express')
const app = express()
app.get('/fibonacci/:num', (req,res) => {
fibonacci(req.params.num).then( (n) => {
res.json({num: n})
})
})
function fibo(n) {
if (n < 2)
return 1;
else
return fibo(n - 2) + fibo(n - 1);
}
const fibonacci = (num) => {
return new Promise((resolve,reject) => {
resolve(fibo(num))
})
}
app.listen(8080, () => {
console.log(`App running on port ${8080}.`)
})

对http://localhost:8080/fibonacci/40的第一次调用大约需要1600毫秒才能完成。

从第二次调用开始,请求几乎需要4600毫秒才能完成。

在下面的例子中,第一个和第二个请求所花费的时间是相同的。

app.get('/dostuff/:num', (req,res) => {
res.json({num: doStuff(req.params.num)})
})
function doStuff(n){
for(let i=0; i<n*10000; i++) { i=i}
}

为什么?

我认为第二个调用需要更长的原因是因为第一个调用仍然在后台运行!

因为你的函数是递归的,fibo(40)导致3.3亿次对fibo()的调用!

为了演示这一点,我修改了代码来跟踪一个迭代器i

const express = require('express')
const app = express()
let i;
app.get('/fibonacci/:num', (req,res) => {
i = 0;
fibonacci(req.params.num).then( (n) => {
console.log(i);
res.json({num: n})
});
});
function fibo(n) {
i++;
if (n < 2)
return 1;
else
return fibo(n - 2) + fibo(n - 1);
}
const fibonacci = (num) => {
return new Promise((resolve,reject) => {
resolve(fibo(num));
});
}
app.listen(8080, () => {
console.log(`App running on port ${8080}.`)
});

/fibonacci/40的请求导致331160281被记录。

我必须承认,我对Node引擎的工作原理了解得不够,无法解释它是如何在几秒钟内得到答案的。我认为这与V8如何整合代码有关。也许有人能解释一下?

最新更新