我正在尝试使用 Oboe.js、MongoDB 和 Express.js 通过 HTTP 进行 JSON 流式传输。
关键是在MongoDB
(Node.js 的 mongodb 本机驱动器)中进行查询,将其(一个 JavaScript 数组)通过管道传输到Express.js
浏览器中并在浏览器中使用Oboe.js
.
我所做的基准streaming
与blocking
MongoDB 查询服务器端和客户端的 JSON 解析进行了比较。
这是两个基准测试的源代码。first number
是a1000 queries
中100 items
(分页)的毫秒数10 million documents collection
,second number
括号之间表示解析 MongoDB 结果数组中的第一项之前的毫秒数。
流媒体基准服务器端:
// Oboe.js - 20238 (16.887)
// Native - 16703 (16.69)
collection
.find()
.skip(+req.query.offset)
.limit(+req.query.limit)
.stream()
.pipe(JSONStream.stringify())
.pipe(res);
阻塞基准服务器端:
// Oboe.js - 17418 (14.267)
// Native - 13706 (13.698)
collection
.find()
.skip(+req.query.offset)
.limit(+req.query.limit)
.toArray(function (e, docs) {
res.json(docs);
});
这些结果真的让我感到惊讶,因为我会认为:
Streaming
会比blocking
每次都快。Oboe.js
JSON.parse
与本机方法相比,解析整个 JSON 数组会更快。Oboe.js
JSON.parse
与本机方法相比,解析数组中的第一个元素会更快。
有人有解释吗?我究竟做错了什么 ?
这也是两个客户端基准测试的源代码。
流式基准测试客户端:
var limit = 100;
var max = 1000;
var oboeFirstTimes = [];
var oboeStart = Date.now();
function paginate (i, offset, limit) {
if (i === max) {
console.log('> OBOE.js time:', (Date.now() - oboeStart));
console.log('> OBOE.js avg. first time:', (
oboeFirstTimes.reduce(function (total, time) {
return total + time;
}, 0) / max
));
return true;
}
var parseStart = Date.now();
var first = true;
oboe('/api/spdy-stream?offset=' + offset + '&limit=' + limit)
.node('![*]', function () {
if (first) {
first = false;
oboeFirstTimes.push(Date.now() - parseStart);
}
})
.done(function () {
paginate(i + 1, offset + limit, limit);
});
}
paginate(0, 0, limit);
阻塞基准客户端:
var limit = 100;
var max = 1000;
var nativeFirstTimes = [];
var nativeStart = Date.now();
function paginate (i, offset, limit) {
if (i === max) {
console.log('> NATIVE time:', (Date.now() - nativeStart));
console.log('> NATIVE avg. first time:', (
nativeFirstTimes.reduce(function (total, time) {
return total + time;
}, 0) / max
));
return true;
}
var parseStart = Date.now();
var first = true;
var req = new XMLHttpRequest();
req.open('GET', '/api/spdy-stream?offset=' + offset + '&limit=' + limit, true);
req.onload = function () {
var json = JSON.parse(req.responseText);
json.forEach(function () {
if (first) {
first = false;
nativeFirstTimes.push(Date.now() - parseStart);
}
});
paginate(i + 1, offset + limit, limit);
};
req.send();
}
paginate(0, 0, limit);
提前致谢 !