我对同步和异步数据转换测试的性能比较感兴趣,以防异步函数立即返回结果。这会影响执行时间吗?
要对此进行检查,我编写了简单的工作台进行检查。
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' } ]
您可以看到执行时间是相同的。对于更高的重复计数,仍然没有太大差异,因此我相信这只是一个鼻子。这样的结果提出了两个问题:
我知道我错过了一些东西,但似乎我忘记考虑一些基本问题。
答案 0 :(得分:2)
要使异步等待正常工作,您的函数应返回一个Promise,但情况并非如此。因此,由于convertAsync不是真正的异步函数,因此您会得到类似的结果。在内部,JavaScript的作用是将函数包装在已解决的Promise中,并且由于您的Promise几乎可以立即得到解决,因此您看到的结果差异很小。
答案 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)
上。