使用Oboe.js,MongoDB和Express.js进行JSONstream式传输

我正在用Oboe.js,MongoDB和Express.js通过HTTP实验JSONstream。

重点是在MongoDB (Node.js的mongodb本地驱动器)中执行查询,将它(一个JavaScript数组)传递给Express.js并使用Oboe.js在浏览器中parsing它。

在MongoDB查询服务器端和客户端的JSONparsing中,我做的基准testing比较了streamingblocking

这是两个基准的源代码。 第first number1000 queries 10 million documents collection100 items (分页)的1000 queries的毫秒second number ,括号之间的second number表示MongoDB结果数组中第一个项目之前的毫秒数parsing。

stream媒体基准服务器端:

 // 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); }); 

这些结果让我感到惊讶,因为我会想:

  1. Streaming比每隔一段时间都要快。
  2. 与原生的JSON.parse方法相比, Oboe.js会更快地parsing整个JSON数组。
  3. 与原生的JSON.parse方法相比, Oboe.js会更快地parsing数组中的第一个元素。

有没有人有解释? 我究竟做错了什么 ?

以下是两个客户端基准的源代码。

stream媒体基准客户端:

 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); 

提前致谢 !

在“为什么是双簧pipe”结尾,我在双簧pipe文件中发现了这些评论。 部分:

因为它是一个纯粹的JavaScriptparsing器,Oboe.js比JSON.parse需要更多的CPU时间。 对于加载非常快的小型消息,Oboe.js稍微慢一点,但对于大多数使用I / O的真实情况,Oboe.js有效地节省了优化CPU时间。 SAXparsing器比Oboe基于模式的parsing模型需要更less的内存,因为它们不构buildparsing树。 看到Oboe.js与SAX与DOM。 如果有疑问,基准,但不要忘记使用真实的互联网,包括手机,并思考感性performance。