gpt4 book ai didi

javascript - Firefox 的递归成本高昂

转载 作者:行者123 更新时间:2023-11-28 02:08:55 24 4
gpt4 key购买 nike

编辑:仅出现在 Firefox 中! (我使用的是 22.0)请参阅底部的浏览器比较。

我试图通过复制像素数据并逐步将 alpha 值从 255 更改为 0(背景为黑色),在 Canvas 上创建“淡入黑色”效果。

function fadeToBlack () {
if(typeof this.recursion === 'undefined' || this.recursion === 0) {
this.recursion = 1;
this.imageData = this.ctx.getImageData(0, 0, this.width, this.height);
this.imageDataArray = this.imageData.data;
this.pixelCount = this.imageDataArray.length/4;
this.fadeToBlack();
}
else if (this.recursion <= 15){
console.time('Change alpha ' + this.recursion);
for (var i = 0; i < this.pixelCount; i++){
this.imageDataArray[i * 4 + 3] = 255 - 255 / 15 * this.recursion;
}
console.timeEnd('Change alpha ' + this.recursion);
this.ctx.putImageData(this.imageData, 0, 0);
this.recursion++;
setTimeout(function(){
this.fadeToBlack();
}.bind(this), 50);
}
else {
this.recursion = 0;
}
};

我认为这会非常昂贵(1280 * 1024 = 1310720 次迭代!),但正如您从下面的控制台日志中看到的,除了第一次迭代之外,它的速度出奇的快。

Change alpha 1: 543ms
Change alpha 2: 16ms
Change alpha 3: 6ms
Change alpha 4: 16ms
...

奇怪的是,如果我只是延迟 fadeToBlack 的第二次迭代(像素操作的第一次迭代)...

function fadeToBlack () {
if(typeof this.recursion === 'undefined' || this.recursion === 0) {
this.recursion = 1;
this.imageData = this.ctx.getImageData(0, 0, this.width, this.height);
this.imageDataArray = this.imageData.data;
this.pixelCount = this.imageDataArray.length/4;
//This is the only difference!
setTimeout(function(){
this.fadeToBlack();
}.bind(this), 0);
}
else if (this.recursion <= 15){
console.time('Change alpha ' + this.recursion);
for (var i = 0; i < this.pixelCount; i++){
this.imageDataArray[i * 4 + 3] = 255 - 255 / 15 * this.recursion;
}
console.timeEnd('Change alpha ' + this.recursion);
this.ctx.putImageData(this.imageData, 0, 0);
this.recursion++;
setTimeout(function(){
this.fadeToBlack();
}.bind(this), 50);
}
else {
this.recursion = 0;
}
};

神奇的事情发生了。

Change alpha 1: 16ms
Change alpha 2: 16ms
Change alpha 3: 6ms
Change alpha 4: 6ms
...

那么这里到底发生了什么?

编辑:我在多个浏览器中对此进行了测试,以下是所有 15 次迭代的结果(以毫秒为单位)。

Browser  |Recursive  |Asynchronous
=========+===========+============
Firefox |1652† |1136
Chrome |976 |978
Opera |12929 |13855
IE |855 |854

†第一次迭代非常昂贵(500ms)。

最佳答案

我认为这将函数之间的跳转减少了一半,因为您只调用一次直到函数终止(当使用 setTimeout 使用异步调用时),但是如果您通过从内部调用来使用递归,它将在该点停止并且跳转到下一个调用,依此类推,直到完成最后一个调用,然后逐渐递归,从停止处调用前一个函数,继续使用递归的返回值并返回到前一个函数,我可以查看绩效和方法方面的出价差异。我想问一下它是否会给出与我怀疑的结果相同的结果。

TL;DR setTimeout:异步调用(独立),递归:同步(依赖)。

图形演示:

enter image description here

关于javascript - Firefox 的递归成本高昂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17397165/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com