Oboe.js、MongoDB、および Express.js を使用して、HTTP を介した JSON ストリーミングを試しています。
ポイントは、MongoDB
(Node.js の mongodb ネイティブ ドライブ) でクエリを実行し、それを (JavaScript 配列) にパイプしてExpress.js
、ブラウザーでOboe.js
.
私が行ったベンチマークは、MongoDB クエリ サーバー側とクライアント側での JSON 解析の両方でstreaming
比較しました。blocking
2 つのベンチマークのソース コードを次に示します。はof (ページネーション)のfirst number
ミリ秒数で、括弧の間は、MongoDB 結果配列の最初の項目が解析されるまでのミリ秒数を表します。1000 queries
100 items
10 million documents collection
second number
サーバー側のストリーミング ベンチマーク:
// 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
ネイティブメソッドと比較して、配列の最初の要素を解析する方が高速です。
誰か説明がありますか?私は何を間違っていますか?
2 つのクライアント側ベンチマークのソース コードもここにあります。
クライアント側のストリーミング ベンチマーク:
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);
前もって感謝します !