对一个巨大的数组进行并行或同步迭代会更快吗?
Would it be faster to iterate over a giant array in parallel or synchronously?
给定一个巨大的数组和一个单核机器,并行迭代数组还是顺序迭代数组更快?假设迭代过程中没有做任何工作,它实际上只是遍历数组。
我的直觉告诉我按顺序做会更快,但我无法用我对操作系统和处理器的了解来证明这个答案是正确的。这两种方式似乎都必须完成相同数量的工作,但是并行执行将为上下文切换带来额外的复杂性。
这个问题的真实世界扩展是javascript的forEach
方法。本地forEach
同步执行它的回调
var a = [1,2,3,4,5,6...100000000000000];
a.foreach(function(number) {
// do computationally expensive, synchronous operation eg lots of additions/multiplications
});
console.log('done iterating through for loop and doing all of the work')
对于上述代码使用异步版本的forEach是否有利(特别是考虑到js只能利用单个核心)?
如果我们做同样的问题,但是异步工作,forEach回调将在阻塞操作发生后立即变为异步。
var a = [1,2,3,4,5,6...100000000000000];
a.foreach(function(number) {
// do asynchronous work, eg access to filesystem
$.ajax({
url: 'http://google.com',
success: function() {
console.log('suceeded for ' + number)
})
});
console.log('done iterating through for loop but not with all async operations')
在这种情况下,使用异步版本的forEach是否有利?似乎我们已经在同步版本中更好地利用了CPU,只切换到IO,而不是在启动IO之前切换。
只要你使用的是单核,那么做某种并行操作就没有任何优势。您是正确的,设置多个任务/线程会对每个任务/线程产生一定数量的开销。并且在并行操作之间分时使用单核会在每个任务切换上产生开销。顺序迭代没有这样的开销。并行操作的唯一优势是当你有多个内核的时候。
现代cpu都是流水线的,大多数都是超标量的。但是,尝试某种并行操作并不会"填充管道"或填充超标量单元。我不知道有哪个Javascript引擎能做到这一点。
哦,只是为了记录,你最好使用for循环而不是foreach。原因很简单,foreach在每次传递时都必须调用一个函数,即使它是一个匿名函数。调用函数会产生一定的开销。在for循环中,函数的内容被内联到循环体中,因此不会有这样的开销。这在其他论坛上有广泛的争论,但我自己的经历证实了这一事实。
这完全取决于代码(很高兴您提供了这一点)。所以你第一个问题的答案应该是No。第二个问题这取决于。
如果代码在单核机器中是全CPU限制的,同步版本会稍微快一点。如果有任何IO绑定代码,异步版本将在同一台机器上更快。因为访问IO不处理CPU。
只有在多核机器上,cpu绑定代码在异步模式下运行会更快。IO绑定代码仍然会比同步代码运行得快。
这是一个汇总表,
type cpu bound io bound mixed
-------------------------------------------------------------------
single-core synchronous normal slower slower
single-core asynchronous normal faster faster
multi-core synchronous normal slower slower
multi-core asynchronous faster faster faster
指出:
- 它假设在一次迭代中运行的所有代码都不依赖于彼此。
- 在大多数现实生活中,我们想并行化的代码是IO和CPU的混合。
- 很难分离IO绑定&CPU绑定部分
- 如何在javascript中迭代数字列表
- JS:检查URL中的参数,然后迭代一个参数为var的函数
- 如何迭代Array.prototype函数
- 如何使用jquery迭代具有相同属性的html元素并查找onclick事件
- 在ejs-partial中对JSON对象进行迭代
- 如何在DataTables 2.1中迭代对象数组
- 使用递归属性迭代保留属性结构
- 正在停止.在jquery中的特定时间间隔内,每次迭代的每次执行
- 如果30秒未单击,请应用CSS一次,将其删除,然后重新迭代
- 主干-从模板中迭代的集合中获取特定的模型
- 创建一个方法,通过一个窗口进行迭代并获取Titanium中的所有控件
- 什么's是在javascript中迭代项的最佳方式
- 为什么这只是迭代 HTMLCollection 的奇怪元素
- 是否“;对于的“;循环迭代遵循JavaScript中的数组顺序
- Babel编译错误:找不到模块核心js/library/fn/get迭代器
- 在es6中,将带有回调的事件侦听器设置为可迭代的
- JavaScript 范围/代码迭代不同步
- 对一个巨大的数组进行并行或同步迭代会更快吗?
- 如何在循环中同步运行AJAX(在下一次迭代之前阻塞)
- Node.js同步循环或迭代异步语句