javascript - 为什么异步函数比同步函数需要更多时间来执行?

标签 javascript asynchronous recursion time async-await

我编写了两个递归函数,对数组中的数字进行求和。他们做同样的事情,一个异步,另一个同步。异步函数花费的时间大约是同步函数的9倍

异步函数不应该利用同时运行更多任务的事实吗?

功能

// Asynchronously sum the numbers in array
async function sumAsync(arr){

    if(arr.length == 1) return arr[0];

    const half = arr.length/2;

    // Numbers on the left half
    const left = arr.filter((e, i) => {
        return i < half;
    });

    // Numbers on the right half
    const right = arr.filter((e, i) => {
        return i >= half;
    });

    // Recursive call
    const leftR = sumAsync(left);
    const rightR = sumAsync(right);

    // Wait for resolves
    await Promise.all([leftR, rightR]);

    return await leftR + await rightR;
}


// Synchronously sum the numbers in array
function sumSync(arr){

    if(arr.length == 1) return arr[0];

    const half = arr.length/2;

    // Numbers on the left half
    const left = arr.filter((e, i) => {
        return i < half;
    });

    // Numbers on the right half
    const right = arr.filter((e, i) => {
        return i >= half;
    });

    // Recursive call
    const leftR = sumSync(left);
    const rightR = sumSync(right);

    return leftR + rightR;
}

测试它们

(async () => {

    const LENGTH = 1048576; // 1024^2
    const arr = Array.from(Array(LENGTH), num => Math.random()*10 | 0);
    //  arr[1048576] <- random (0 ~ 9)

    // Async sum
    console.log('ASYNC');
    before = Date.now();
    console.log(`SUM: ${await sumAsync(arr)}`);
    after = Date.now();
    console.log(`TIME: ${after - before} ms`);

    // Sync sum
    console.log('SYNC');
    before = Date.now();
    console.log(`SUM: ${sumSync(arr)}`);
    after = Date.now();
    console.log(`TIME: ${after - before} ms`);

})();

结果

// ASYNC
// SUM: 4720832
// TIME: 5554 ms

// SYNC
// SUM: 4720832
// TIME: 613 ms

最佳答案

async 的返回值函数始终是一个 Promise,即使该函数仅执行同步操作,并且 await Promise 的(或 .then )只会运行微任务期间的后续内容(当前同步代码运行完毕后)。对于大型数组,这将导致大量不必要的微任务包装同步代码。

当没有任何实际异步发生时,这只是额外的负担,并导致额外的处理时间和所需的电量。

Shouldn't the async function take advantage from the fact of running more tasks at the same time?

Javascript 是单线程的,即使有 async功能。如果同时调用多个异步函数,则在任何时候只有一个代码路径可能是“事件的”。如果在标准 Javascript 中所有任务所需的总处理时间是 1000 毫秒,那么就不可能至少花费 1000 毫秒。

您实际上并没有同时运行更多任务 - 您只是将任务包装在 Promise 中(不必要),同时执行相同的工作。

对于真正的并行操作,您必须使用当前环境提供的东西,例如 child_process在节点中,或 web worker .

关于javascript - 为什么异步函数比同步函数需要更多时间来执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60330963/

相关文章:

javascript - overflow-x 时在 CSS 中水平滚动

c# - 异步鸡和蛋故事的最佳解决方案

javascript - 使用 Mocha/Chai 测试异步函数时,无法满足期望总是会导致超时

python - 递归函数内存使用

javascript - 在 Javascript 中返回 undefined object 属性

algorithm - 查找点,距离和线上所有其他点的总和是最低的

javascript - JQuery - 根据数据库中的值使用 ajax 突出显示元素

javascript - 使用内置版本的 Dojo 时出错(但不是未压缩的源代码)

javascript - 如何使用 AngularJS 表单上传图像 - 后端 : PHP

c# - C# Task.WaitAll() 如何将对象状态合二为一?