我正在编写一个将图像逐个像素地绘制到画布元素的函数。我注意到有一点,功能突然变得比以前更长 - 特别是从338x338像素画布到339x339像素画布。
将相似的函数放入jsfiddle,我得到相同的结果。 while循环处理一个338x338的数组需要大约。 6-7秒,而339x339的阵列大约需要6到9秒。 24-25秒。
这种情况发生在Chrome上。在Firefox中,两者都需要大约。 16秒。
这是小提琴: http://jsfiddle.net/8pb89/5/
代码如下所示:
var ary1 = [];
var ary2 = [];
var mapData = {};
var colorMatrix = {};
for (var i = 0; i < (338 * 338); i++) {
ary1.push([i, i + 2]);
}
for (var i = 0; i < (339 * 339); i++) {
ary2.push([i, i + 2]);
}
//Light operation
function test(i, j) {
return Math.floor((i * j + i + j) / j);
}
//Heavy operation on objects
function calcTest(ary){
var point = ary.splice(0, 1);
var i = point[0];
var j = point[1];
if (!mapData[i]) {
mapData[i] = [];
}
if (!mapData[i][j]) {
mapData[i][j] = [];
}
mapData[i][j]["one"] = test(i, j);
mapData[i][j]["two"] = test(i, j);
colorMatrix[mapData[i][j]["two"]] = mapData[i][j]["one"];
}
var len = ary1.length;
var start = new Date().getTime();
while (len--) {
calcTest(ary1);
}
var end = new Date().getTime();
var time = end - start;
alert('Execution for 338x338: ' + time);
var len2 = ary2.length;
obj = {};
obj2 = {};
start = new Date().getTime();
while (len2--) {
calcTest(ary2);
}
end = new Date().getTime();
time = end - start;
alert('Execution for 339x339: ' + time);
这是Chrome上javascript的内存问题,还是我对这些对象做错了?有没有办法避免这个更高的处理持续时间?
答案 0 :(得分:1)
我猜它是以下一种或两种。
338 * 338
和339 * 339
之间的基础哈希表的大小。 我怀疑这是一个记忆问题。
答案 1 :(得分:1)
考虑您的SPLICE操作实际上在做什么。让我们一起来拼接这个数组:
[0,1,2,3,4,5]
我必须:
STORE the 0
READ the 1, WRITE to where the 0 was
READ the 2, WRITE to where the 1 was
READ the 3, WRITE to where the 2 was
READ the 4, WRITE to where the 3 was
READ the 5, WRITE to where the 4 was
DELETE the 5
这是12个操作(在6个项目的数组上)...你的数组更大,更大(超过100k项目)......并且你正在迭代它们,随着它们缩小它们。我在你的代码中进行了大约260亿次计算!!!
我已经重新考虑你的代码将while循环放在测试中而不使用SPLICE函数 - 我现在在我的机器上将测试降低到23ms和25ms(达到与测试相同的结果)......你的例子花了3599毫秒和19464毫秒 - 效率提高了近500倍:)
此代码还有许多其他问题,但这是您最大问题的核心所在!
var ary1 = [];
var ary2 = [];
var mapData = {};
var colorMatrix = {};
for (var i = 0; i < (338 * 338); i++) {
ary1.push([i, i + 2]);
}
for (var i = 0; i < (339 * 339); i++) {
ary2.push([i, i + 2]);
}
//Light operation
function test(i, j) {
return Math.floor((i * j + i + j) / j);
}
//Heavy operation on objects
function calcTest(ary){
for (index=ary.length-1;index>=0;index--){
var point=ary[index];
var i = point[0];
var j = point[1];
if (!mapData[i]) {
mapData[i] = [];
}
if (!mapData[i][j]) {
mapData[i][j] = [];
}
mapData[i][j]["one"] = test(i, j);
mapData[i][j]["two"] = test(i, j);
colorMatrix[mapData[i][j]["two"]] = mapData[i][j]["one"];
}
}
//I'm only putting the following lines in first to show that the first
//Operation takes longer by populating the mapData and colorMatrix arrays
//If you delete the next two lines you'll find that the 339 option takes
//less time than the 338 (because it's going second!)
calcTest(ary1);
calcTest(ary2);
var start = new Date().getTime();
calcTest(ary1);
var end = new Date().getTime();
var time = end - start;
alert('Execution for 338x338: ' + time);
start = new Date().getTime();
calcTest(ary2);
end = new Date().getTime();
time = end - start;
alert('Execution for 339x339: ' + time);