同步与即时异步执行性能基准

时间:2018-09-25 17:54:12

标签: javascript node.js promise async-await

我对同步和异步数据转换测试的性能比较感兴趣,以防异步函数立即返回结果。这会影响执行时间吗?

要对此进行检查,我编写了简单的工作台进行检查。

const { performance } = require('perf_hooks');

const data = JSON.stringify((() => {
    const obj = {};
    for (let i = 0; i < 1000; i++) {
        obj[i] = i;
    }
    return obj;
})());

function convertSync (data) {
    return JSON.parse(data);
}

async function convertAsync (data) {
    return JSON.parse(data); 
}

const REPEAT_COUNT = 10000;

performance.mark("sync_start");
for (let i = 0; i < REPEAT_COUNT; i++) {
    convertSync(data);
}
performance.mark("sync_end");

performance.mark("async_start");
Promise.resolve()
    .then(async () => {
        for (let i = 0; i < REPEAT_COUNT; i++) {
            await convertAsync(data);
        }
        performance.mark("async_end");
    })
    .then(async () => {
        performance.measure("sync", "sync_start", "sync_end");
        performance.measure("async", "async_start", "async_end");

        console.log("REPEAT_COUNT", REPEAT_COUNT);
        console.log(performance.getEntries().filter(x => x.entryType === "measure"));
    }) 

我正在使用没有任何编译器的Node v8.11.1,并获得了以下结果。

PS D:\TestProjects\PerfTest\promisevssync> node .\index.js
REPEAT_COUNT 100000
[ PerformanceEntry {
    duration: 7825.5724,
    startTime: 383379071.208899,
    entryType: 'measure',
    name: 'sync' },
  PerformanceEntry {
    duration: 7836.966301,
    startTime: 383386896.834899,
    entryType: 'measure',
    name: 'async' } ]
PS D:\TestProjects\PerfTest\promisevssync> node .\index.js
REPEAT_COUNT 10000
[ PerformanceEntry {
    duration: 788.824201,
    startTime: 383405055.485299,
    entryType: 'measure',
    name: 'sync' },
  PerformanceEntry {
    duration: 798.591301,
    startTime: 383405844.370999,
    entryType: 'measure',
    name: 'async' } ]

您可以看到执行时间是相同的。对于更高的重复计数,仍然没有太大差异,因此我相信这只是一个鼻子。这样的结果提出了两个问题:

  1. 此测试正确吗?
  2. 为什么?

我知道我错过了一些东西,但似乎我忘记考虑一些基本问题。

2 个答案:

答案 0 :(得分:2)

要使异步等待正常工作,您的函数应返回一个Promise,但情况并非如此。因此,由于convertAsync不是真正的异步函数,因此您会得到类似的结果。在内部,JavaScript的作用是将函数包装在已解决的Promise中,并且由于您的Promise几乎可以立即得到解决,因此您看到的结果差异很小。

看看https://javascript.info/async-await

答案 1 :(得分:2)

  

我对同步和异步数据转换测试的性能比较感兴趣,以防异步函数立即返回结果。这会影响执行时间吗?

测量是正确的,但是请注意,测量的是同步和异步迭代的性能,而数据转换保持同步。

Node.js具有高分辨率计时器,因此承诺自己只会带来微小的延迟 与convertAsync通话所花费的时间相比,可以忽略不计。

这项经过10000次迭代的测试证实了这一点:

for (let i = 0; i < REPEAT_COUNT; i++) {}

vs

for (let i = 0; i < REPEAT_COUNT; i++) {
  await null;
}

同步环路的测量值为0.5毫秒,异步环路的测量为9毫秒。

与空转相比,大多数时间都花在JSON.parse(data)上。