Javascript - 为什么在迭代函数中测量时间变得不准确?
Javascript - Why does measuring time becomes inaccurate in a iterating function?
考虑这段代码
// Initialise the variables to check when the code started
let total_time = performance.now();
let recursions = 0;
function test() {
recursions++;
if (recursions === 60) {
// Check how long it took to do 60 recursions
console.log(`${performance.now() - total_time}ms`);
}
// Timeout to call it 17ms later
setTimeout(() => test(), 17);
}
test();
这意味着发生 60 次递归以确保我的代码的某些部分被正确触发(不需要 setTimeout 因为它正在阻塞)并且我无缘无故地在 1200 - 1600 毫秒之间。我使用了一个修改后的版本来测量它花费了多长时间,它给出了 0 毫秒(无缘无故)。有人知道为什么吗? node.js 也会发生同样的事情吗?
用于衡量执行一次递归所用时间的代码
let start_time = performance.now();
let total_time = performance.now();
let measure = 0;
function test() {
start_time = performance.now();
measure++;
if (measure === 60) {
console.log(`${performance.now() - total_time}ms`);
}
console.log(`Taken ${performance.now() - start_time}`);
}
test();
它不应该像您预期的那样非常准确,因为超时可能会在页面忙于其他任务时触发事件。
setTimeout
的实现方式是在 最小 给定延迟后执行,一旦浏览器的线程可以自由执行它。因此,举例来说,如果您为 delay 参数指定一个值 0,并且您认为它会“立即”执行,那么它不会。更准确地说,它将在下一个事件循环中运行(这是事件循环的一部分——负责执行代码的并发模型)。
总而言之,如果您希望获得一致、可靠的结果,则不能使用 setTimeout
和精确的毫秒级计时。
请阅读延误时间超过指定时间的原因 - https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#reasons_for_delays_longer_than_specified
关于 JS 事件循环的更多信息 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
考虑这段代码
// Initialise the variables to check when the code started
let total_time = performance.now();
let recursions = 0;
function test() {
recursions++;
if (recursions === 60) {
// Check how long it took to do 60 recursions
console.log(`${performance.now() - total_time}ms`);
}
// Timeout to call it 17ms later
setTimeout(() => test(), 17);
}
test();
这意味着发生 60 次递归以确保我的代码的某些部分被正确触发(不需要 setTimeout 因为它正在阻塞)并且我无缘无故地在 1200 - 1600 毫秒之间。我使用了一个修改后的版本来测量它花费了多长时间,它给出了 0 毫秒(无缘无故)。有人知道为什么吗? node.js 也会发生同样的事情吗?
用于衡量执行一次递归所用时间的代码
let start_time = performance.now();
let total_time = performance.now();
let measure = 0;
function test() {
start_time = performance.now();
measure++;
if (measure === 60) {
console.log(`${performance.now() - total_time}ms`);
}
console.log(`Taken ${performance.now() - start_time}`);
}
test();
它不应该像您预期的那样非常准确,因为超时可能会在页面忙于其他任务时触发事件。
setTimeout
的实现方式是在 最小 给定延迟后执行,一旦浏览器的线程可以自由执行它。因此,举例来说,如果您为 delay 参数指定一个值 0,并且您认为它会“立即”执行,那么它不会。更准确地说,它将在下一个事件循环中运行(这是事件循环的一部分——负责执行代码的并发模型)。
总而言之,如果您希望获得一致、可靠的结果,则不能使用 setTimeout
和精确的毫秒级计时。
请阅读延误时间超过指定时间的原因 - https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#reasons_for_delays_longer_than_specified
关于 JS 事件循环的更多信息 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop