date - 在 JavaScript 中使用 setTimeout 让函数运行更快
我有一个应用程序,我必须向数组中推送很多值,所以我测试了执行时间:
var st = new Date().getTime();
var a = [];
for (var i = 0; i < 20971520; i++) {
a.push(i);
}
var ed = new Date().getTime();
console.info((ed - st) / 1000);
console.info(a.length);
我直接在 Firefox 控制台和 Chrome 控制台运行代码,耗时 37 秒。在执行过程中,即使在 Chrome 中鼠标可以移动,但没有互动效果。
然后我更改了代码:
function push() {
var st = new Date().getTime();
var a = [];
for (var i = 0; i < 20971520; i++) {
a.push(i);
}
var ed = new Date().getTime();
console.info((ed - st) / 1000);
console.info(a.length);
}
var tr = setTimeout(push, 50);
将代码简化放入一个函数中,并使用 setTimeout 调用它,耗时 0.844 秒。在执行期间,我可以正常在 Chrome 中操作。
这里发生了什么?
我知道 setTimeout 会将控制权交给浏览器来处理 UI 工作,这会使页面保持响应。例如,当我在页面的 mousemove 期间进行一些计算时,我会将计算延迟执行,以防止它阻塞 UI。
但是为什么它会减少相同代码的总执行时间?
答案#1
在执行过程中,我可以正常在 Chrome 中操作。
不对。主 Chrome 窗口会像其他情况一样冻结(只是时间更短)。调试工具是独立的线程,不会变慢。
但是为什么它会减少相同代码的总执行时间?
如果你在开发工具中运行,它确实会这样。如果你在实际环境中执行代码,让虚拟机可以进行属性优化,时间是可比较的(几乎1秒)。例如。
var st = new Date().getTime();
var a = [];
for (var i = 0; i < 20971520; i++) {
a.push(i);
}
var ed = new Date().getTime();
console.info('normal', (ed - st) / 1000);
console.info(a.length);
function push() {
var st = new Date().getTime();
var a = [];
for (var i = 0; i < 20971520; i++) {
a.push(i);
}
var ed = new Date().getTime();
console.info('timeout', (ed - st) / 1000);
console.info(a.length);
}
var tr = setTimeout(push, 0);
http://jsfiddle.net/gu9Lg52j/ 你会看到 normal 执行得 和 setTimeout 一样快。
另外,如果你将代码包装在一个函数中并在控制台中执行,即使没有 setTimeout,时间也会是可比的,因为虚拟机可以在函数定义和执行之间进行优化:
function push() {
var st = new Date().getTime();
var a = [];
for (var i = 0; i < 20971520; i++) {
a.push(i);
}
var ed = new Date().getTime();
console.info('timeout', (ed - st) / 1000);
console.info(a.length);
}
push();
答案#2
这两种代码变体的运行速度应该几乎相同(后一个示例可能更快,但不会快十倍)。
在 Chrome 开发者工具中,情况就不同了。表达式是在一个 with 块内进行求值的。这意味着像 a 和 i 这样的变量会先在另一个对象(__commandLineAPI)中搜索。这增加了额外的开销,从而导致执行时间长了 10 倍。
