通过多次调用计算异步函数的执行时间
calculate execution times of async function over multiple calls
如果 do work 函数正在执行一些操作,例如,从队列中挑选一个项目并执行一些操作。随着时间的推移,我将如何获得 doWork
函数的执行时间。我想知道 doWork
平均需要多少时间才能完成。
示例代码
function doWork () {
return Promise.resolve({first: 'Tony', last: 'Starks'})
}
async function wrapper () {
console.time('wrapper')
const response = await doWork()
console.timeEnd('wrapper')
return response
}
Promise.all([
wrapper(),
wrapper(),
wrapper()
]).then((result) => console.info(result))
输出
wrapper: 0.388ms
[ { first: 'Tony', last: 'Starks' },
{ first: 'Tony', last: 'Starks' },
{ first: 'Tony', last: 'Starks' } ]
(node:2749) Warning: No such label 'wrapper' for console.timeEnd()
(node:2749) Warning: No such label 'wrapper' for console.timeEnd()
如果您只是想让 console.time()
和 console.end()
调用绕过您的异步函数,您可以在每次调用 console.time()
和 console.end()
这样当有多个调用同时进行时测量仍然有效(因为每个调用都将使用自己的标签):
let wrapperCntr = 0;
async function wrapper () {
let cnt = wrapperCntr++;
console.time('wrapper' + cnt);
const response = await doWork();
console.timeEnd('wrapper' + cnt);
return response;
}
如果您很难同时测试它们,我推荐这种方法:
function doWork () {
return Promise.resolve({ first: 'Tony', last: 'Stank' })
}
async function wrapper (index) {
console.time(index)
const response = await doWork()
console.timeEnd(index)
return response
}
Promise.all(
Array(3) // some big number
.fill(wrapper)
.map((wrapper, index) => wrapper(index))
).then((results) => console.info(results))
但是,JavaScript 是单线程的。您在同一时间段内初始化了 3 个异步函数。他们最终在每个异步回调上竞争 CPU 时间,正如您所观察到的,这会导致不当的时间延迟。
比较上面和下面的时间;下面将快一个数量级,因为它们是按顺序初始化的,不会竞争 CPU 时间:
function doWork () {
return Promise.resolve({ first: 'Tony', last: 'Stank' })
}
async function wrapper ({ index, responses }) {
console.time(index)
responses.push(await doWork())
console.timeEnd(index)
return { index: ++index, responses }
}
Array(3) // some big number
.fill(wrapper)
.reduce(
(promise, wrapper) => promise.then(wrapper),
Promise.resolve({ index: 0, responses: [] })
)
.then(({ responses: results }) => console.info(results))
为什么不使用内置的 performance 包,它默认在 node 和浏览器中可用。
以下也适用于多个调用...
async function timePromise(promiseFunction) {
try {
const begin = performance.now();
await promiseFunction();
const end = performance.now();
const timeTaken_ms = end - begin;
return timeTaken_ms;
} catch (error) {
console.error(error);
}
}
如果 do work 函数正在执行一些操作,例如,从队列中挑选一个项目并执行一些操作。随着时间的推移,我将如何获得 doWork
函数的执行时间。我想知道 doWork
平均需要多少时间才能完成。
示例代码
function doWork () {
return Promise.resolve({first: 'Tony', last: 'Starks'})
}
async function wrapper () {
console.time('wrapper')
const response = await doWork()
console.timeEnd('wrapper')
return response
}
Promise.all([
wrapper(),
wrapper(),
wrapper()
]).then((result) => console.info(result))
输出
wrapper: 0.388ms
[ { first: 'Tony', last: 'Starks' },
{ first: 'Tony', last: 'Starks' },
{ first: 'Tony', last: 'Starks' } ]
(node:2749) Warning: No such label 'wrapper' for console.timeEnd()
(node:2749) Warning: No such label 'wrapper' for console.timeEnd()
如果您只是想让 console.time()
和 console.end()
调用绕过您的异步函数,您可以在每次调用 console.time()
和 console.end()
这样当有多个调用同时进行时测量仍然有效(因为每个调用都将使用自己的标签):
let wrapperCntr = 0;
async function wrapper () {
let cnt = wrapperCntr++;
console.time('wrapper' + cnt);
const response = await doWork();
console.timeEnd('wrapper' + cnt);
return response;
}
如果您很难同时测试它们,我推荐这种方法:
function doWork () {
return Promise.resolve({ first: 'Tony', last: 'Stank' })
}
async function wrapper (index) {
console.time(index)
const response = await doWork()
console.timeEnd(index)
return response
}
Promise.all(
Array(3) // some big number
.fill(wrapper)
.map((wrapper, index) => wrapper(index))
).then((results) => console.info(results))
但是,JavaScript 是单线程的。您在同一时间段内初始化了 3 个异步函数。他们最终在每个异步回调上竞争 CPU 时间,正如您所观察到的,这会导致不当的时间延迟。
比较上面和下面的时间;下面将快一个数量级,因为它们是按顺序初始化的,不会竞争 CPU 时间:
function doWork () {
return Promise.resolve({ first: 'Tony', last: 'Stank' })
}
async function wrapper ({ index, responses }) {
console.time(index)
responses.push(await doWork())
console.timeEnd(index)
return { index: ++index, responses }
}
Array(3) // some big number
.fill(wrapper)
.reduce(
(promise, wrapper) => promise.then(wrapper),
Promise.resolve({ index: 0, responses: [] })
)
.then(({ responses: results }) => console.info(results))
为什么不使用内置的 performance 包,它默认在 node 和浏览器中可用。
以下也适用于多个调用...
async function timePromise(promiseFunction) {
try {
const begin = performance.now();
await promiseFunction();
const end = performance.now();
const timeTaken_ms = end - begin;
return timeTaken_ms;
} catch (error) {
console.error(error);
}
}