Node.js:async.map变慢

GnxR

你好,

我使用Node.js提供了一个用于在MongoDB数据库上存储数据的API。

我对一个read方法进行了多个测试,该方法使用id并返回相应的文档。关键是我必须按指定顺序退回这些文件。为了确保这一点,我使用以下代码:

// Sequentially fetch every element
function read(ids, callback) {
    var i = 0;
    var results = [];
    function next() {
        db.findOne(ids[i], function (err, doc) {
            results.push(err ? null : doc);
            if (ids.length > ++i) {
                return next();
            }
            callback(results);
        });
    }
    next();
}

这样,可以以正确的顺序一张一张地提取文档。我的笔记本电脑上大约需要11秒钟才能检索到27k个文档。

但是,我认为可以改进此方法:

// Asynchronously map the whole array
var async = require('async');

function read(ids, callback) {
    async.map(ids, db.findOne.bind(db), callback):
}

在运行了一个测试之后,我很满意地看到使用更简单的代码仅用8秒钟就检索到27k文档。

当我重复相同的请求的问题发生:响应时间不断增加(成比例的元素检索到的数): 9s 10s 11s 12s...在顺序版本中不会发生此问题。

我尝试了两个版本的Node.js,分别是v6.2.0和v0.10.29。问题是一样的。是什么导致了这种延迟,我该如何抑制呢?

vp_arth

尝试使用async.mapLimit以防止过载。您需要进行一些测试,以根据环境调整极限值。


但是find({_id: {$in: list}})总会更好,因为单个数据库请求而不是多个数据库请求。

我建议您尝试执行原始订单客户端的还原。
像这样的东西:

function read(ids, cb) {
  db.find(
    {_id: {$in: ids.map(id => mongoose.Types.ObjectId(id))}},
    process
  );

  function process(err, docs) {
    if (err) return cb(err);
    return cb(null, docs.sort(ordering))
  }
  function ordering(a, b) {
    return ids.indexOf(b._id.toString()) - ids.indexOf(a._id.toString());
  }
}

可能是,查找查询需要更正,我不知道您使用了什么确切的mongodb驱动程序。

该代码是第一个尝试的代码,更多的手动排序可以大大提高性能。[].indexOf也很重(O(n))。
但我几乎可以肯定,即使现在,它的运行速度也要快得多。


可能的ordering替换:

var idHash = {};
for(var i = 0; i < ids.length; i++)
  idHash[ids[i]] = i;
function ordering(a, b) {
  return idHash[b._id.toString()] - idHash[a._id.toString()];
}

任何排序算法O(nlogn)在最佳情况下都有,但是我们已经知道每个找到的文档的结果位置,因此,我们可以通过O(n)以下方法恢复原始顺序

var idHash = ids.reduce((c, id, i) => (c[id] = i, c), {});
function process(err, docs) {
  if (err) return cb(err);
  return cb(null, 
    docs.reduce(
      (c, doc) => (c[idHash[doc._id.toString()]] = doc, c),
      ids.map(id => null))) //fill not_found docs by null
}

功能风格使代码更加灵活。例如,可以轻松修改此代码async.reduce以减少同步阻塞。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

async.map不会在Node.js中调用回调

来自分类Dev

Node.JS中的ASYNC

来自分类Dev

了解Node.JS async.parallel

来自分类Dev

Node.js中的async / await替换

来自分类Dev

node.js中的async.eachSeries

来自分类Dev

.net中的Node.js与Async / await

来自分类Dev

node.js嵌套async.eachSeries

来自分类Dev

Node JS Async Promise。所有问题

来自分类Dev

Node.js中的async / await替换

来自分类Dev

使用 Node js Await/Async 函数

来自分类Dev

与Node js async / await相比,了解Python async / await

来自分类Dev

Node.js-到http响应的pipe()导致ubuntu上的响应时间变慢

来自分类Dev

node.js async.js nextTick与setImmediate

来自分类Dev

Node.js,Mongo async.js插入和查询

来自分类Dev

Node.JS的Async.js出现问题

来自分类Dev

Node.js Asynchronous Library Comparison - Q vs Async

来自分类Dev

async.each是非阻塞的吗?node.js

来自分类Dev

关于node.js中async.waterfall的问题

来自分类Dev

Node.js在Async上创建简单队列

来自分类Dev

对Node.js的async.parallel()的调用是否同步?

来自分类Dev

关于node.js中async.waterfall的问题

来自分类Dev

使用async.forEach和异步操作的Node.js

来自分类Dev

如何在async.waterfall Node.js中循环

来自分类Dev

在Node.js中将Async与Waterfall和Recursion结合使用

来自分类Dev

Javascript (node.js) Promise async/await 问题

来自分类Dev

WriteError/QuotaExceededError Browserify IPFS ASYNC node.js

来自分类Dev

使用嵌套的async.forEachSeries和async.waterfall控制Lambda Node.js代码的排序

来自分类Dev

node.js - 使用 .map 来丰富对象

来自分类Dev

使用node.js和async.js:系列执行顺序错误?