javascript - 并行或同步迭代一个巨大的数组会更快吗?

标签 javascript concurrency parallel-processing

给定一个巨大的数组和一个单核机器,并行或顺序迭代数组会更快吗?假设迭代过程中没有完成任何工作,它实际上只是在数组上进行迭代。

我的直觉告诉我,按顺序执行会更快,但我无法以我对操作系统和处理器的了解来证明答案的合理性。看起来无论哪种方式都必须完成相同数量的工作,但并行执行会给上下文切换带来额外的复杂性。

这个问题的现实世界扩展是 javascript 的 forEach 方法。 native 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 的异步版本会有优势吗? 看起来我们已经通过仅切换 IO 来更好地利用同步版本中的 CPU在我们启动 io 之前进行切换。

最佳答案

只要您使用单核,执行某种并行操作就没有任何优势。您是正确的,设置多个任务/线程会给每个任务/线程带来一定的开销。跨并行操作分时单个核心会在每个任务切换上产生开销。顺序迭代没有这样的开销。并行操作唯一具有优势的时候是当您拥有多个核心时。

现代 CPU 都是流水线式的,并且大多数都是超标量启动的。但是尝试某种并行运算并不会“填充管道”或填充超标量单元。我不知道有任何 Javascript 引擎可以做到这一点。

哦,郑重声明一下,使用 for 循环比使用 foreach 更好。原因很简单,foreach 必须在每次传递时调用一个函数,即使它是一个匿名函数。调用函数会产生一定的开销。 for 循环中,函数的内容内联到循环体中,因此不会有这样的开销。这在其他论坛上已引起广泛争论,但我自己的经验证实了这一事实。

关于javascript - 并行或同步迭代一个巨大的数组会更快吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25211434/

相关文章:

c++ - 两个进程打开同一个文件进行写入

javascript - Facebook Opengraph自定义fb登录按钮

Python - 实现 Future 对象

performance - 与 Entity Framework 平行。与启动多个可执行文件相比,性能是惊人的,为什么呢?

c++ - 使用 boost asio 进行多线程 http 处理是否需要线程?

for-loop - go 中循环和 goroutinues 的意外行为

c++ - 使用 vfork 的多线程

javascript - 完整的 Ajax 站点,自动从 "normal"URL 重定向到 Ajax(片段)URL?

javascript - 用 Javascript 加密,用 PHP 解密,使用公钥加密

javascript - Internet Explorer 和 Base64 图像显示