在Node.JS中,任何使Array.prototype.sort()产生其他进程的方法?

时间:2013-04-13 20:50:44

标签: node.js

仅供参考:我已经和Web Workers一起做了这件事,并且它工作正常,但我只是在探索使用process.nextTick可以做什么和不能做什么。

所以我有一个包含一百万个元素的数组,我在Node.JS中进行排序。我希望Node能够在其执行此操作时响应其他请求。

有没有办法让Array.prototype.sort()不阻止其他进程?由于这是一个核心功能,我无法插入任何process.nextTick()。

我可以手动实现快速排序,但我无法以延续传递方式看到你如何高效地执行此操作,这似乎是process.nextTick()所必需的。我可以修改for循环来执行此操作,但sort()似乎不可能。

3 个答案:

答案 0 :(得分:2)

虽然不可能使Array.prototype.sort以某种方式本身异步运行,但异步排序肯定是可能的,如this sorting demo所示,以证明setImmediate(shim)优于setTimeout的速度优势。

遗憾的是,源代码似乎没有任何许可证。 https://github.com/jphpsf/setImmediate-shim-demo演示的Github回购将Jason Weber命名为作者。您可能想问他是否要使用(部分)代码。

我认为如果你使用setImmediate(从节点0.10开始可用),各个排序操作将与I / O回调有效地交错。对于如此大量的工作,我不推荐process.nextTick(如果它可以工作,因为有1000个maxTickDepth限制)。有些背景,请参阅setImmediate vs. nextTick

使用setImmediate而不是普通的“同步”处理总体上会慢一些,因此您可以选择按“tick”处理一批单独的排序操作以加快速度,但节点是Node在此期间没有响应。我认为I / O的速度和响应能力之间的正确平衡只能通过实验找到。

更简单的替代方法是更像网络工作者:生成子进程并在那里进行排序。然后,您面临的最大问题是将已排序的数据传输回主进程(可能会生成某种输出)。对于Node.js,AFAIK没有类似transferable objects的内容。在缓冲了已排序的数组之后,您可以将结果流式传输到子进程stdout并解析主进程中的数据,或者更简单;使用child process messaging

你可能没有备用的cpu核心,所以子进程会入侵其他进程cpu时间。为避免排序过程损害您的其他进程,您可能需要为其分配低优先级。使用Node本身似乎无法做到这一点,但您可以尝试使用nice,如下所述:https://groups.google.com/forum/#!topic/nodejs/9O-2gLJzmcQ。我没有这方面的经验。

答案 1 :(得分:0)

好吧,我最初认为你可以使用async.sortBy,但经过仔细检查,它似乎不会按你的需要行事。有关类似问题,请参阅Array.sort and Node.js,但目前尚未接受答案。

答案 2 :(得分:0)

我知道这是一个相当老的问题,但是我遇到了类似的情况,但仍然找不到简单的解决方案。

我修改了一种现成的快速排序方法,并发布了一个程序包,该程序包在此处定期放弃对eventloop的执行: https://www.npmjs.com/package/qsort-async

如果您熟悉传统的快速排序,那么我唯一的修改就是对执行分区的初始函数进行修改。基本上,该函数仍会修改数组,但是现在返回一个promise。如果尝试在单个迭代中处理太多元素,它将停止对事件循环中其他事物的执行。 (我相信我指定的默认大小是10000)。

注意:在此处使用setImmedate而不在此处使用process.nextTick或setTimeout很重要。 nextTick实际上会将您的执行放在进程IO之前,并且您在响应与IO相关的其他请求时仍然会遇到问题。 setTimeout太慢了(我相信其他答案之一也与演示有关)。

注2:如果您更喜欢使用mergesort之类的样式,则可以在sort的'merge'函数中执行相同的逻辑。

const immediate = require('util').promisify(setImmediate);

async function quickSort(items, compare, left, right, size) {
  let index;
  if (items.length > 1) {
    index = partition(items, compare, left, right);
    if (Math.abs(left - right) > size) {
      await immediate();
    }
    if (left < index - 1) {
      await quickSort(items, compare, left, index - 1, size);
    }
    if (index < right) {
      await quickSort(items, compare, index, right, size);
    }
  }
  return items;
}

完整代码在这里:https://github.com/Mudrekh/qsort-async/blob/master/lib/quicksort.js