Javascript JS中700毫秒内的800万次迭代可以吗?如何加速?
我有一个游戏和初始化地图2000 x 4000块。 仅在加载时运行一次,需要约700毫秒。我怎样才能加快速度?其他逻辑取决于这张地图。 代码如下:Javascript JS中700毫秒内的800万次迭代可以吗?如何加速?,javascript,performance,Javascript,Performance,我有一个游戏和初始化地图2000 x 4000块。 仅在加载时运行一次,需要约700毫秒。我怎样才能加快速度?其他逻辑取决于这张地图。 代码如下: var start = new Date(); var g = {}; g.world = { h:2000, w:4000, cellInfo: [] }; var i, j, world = g.world, hlim = world.h, wlim = world.w, cellInfo = world.cell
var start = new Date();
var g = {};
g.world = { h:2000, w:4000, cellInfo: [] };
var i, j,
world = g.world,
hlim = world.h,
wlim = world.w,
cellInfo = world.cellInfo;
for ( i = hlim; i; i--) {
cellInfo[i] = [];
for (j = wlim; j; j--) {
cellInfo[i][j] = 1;
}
}
g.world.cellInfo = cellInfo;
alert(new Date() - start);
这里是fiddle:为您提供了几个选项: 惰性初始化 加快速度的最佳方法是使用延迟初始化。例如,与其初始化所有800万个插槽,不如让依赖它们的代码在不存在时处理它们。例如,得到一个手机
function getCell(x, y) {
var row, cell;
row = cellInfo[x];
if (!row) {
row = cellInfo[x] = [];
}
cell = row[y];
if (typeof cell === "undefined") {
cell = row[y] = 1; // 1 appears to be the default value
}
return cell;
}
…并且类似于setCell
。这就展开了初始化。当然,这意味着事情会稍微慢一点,尽管这不太可能有明显的区别
阵列克隆
如果不这样做,另一种选择是创建4000插槽阵列一次,然后克隆它,而不是手动创建,希望在JavaScript引擎中完成工作比自己完成实际循环更快:
// ...
var the4k = [];
// ...build it...
// Now use it for one row and clone it for the others
cellInfo[hlim] = the4k;
for ( i = hlim - 1; i; i--) {
cellInfo[i] = the4k.slice(0);
}
阵列克隆对我来说,Chrome从~780ms到~130ms,IE9从~530ms到~50ms
另一个要考虑的问题是,在IE8和更早的时候,“慢脚本警告”不是基于时间,而是基于操作的数量。你的小提琴在IE8上给了我慢脚本警告。我的没有
IE8支持lazy init,因为即使运行我的小提琴版本也需要将近9秒的时间。 惰性初始化 加快速度的最佳方法是使用延迟初始化。例如,与其初始化所有800万个插槽,不如让依赖它们的代码在不存在时处理它们。例如,得到一个手机
function getCell(x, y) {
var row, cell;
row = cellInfo[x];
if (!row) {
row = cellInfo[x] = [];
}
cell = row[y];
if (typeof cell === "undefined") {
cell = row[y] = 1; // 1 appears to be the default value
}
return cell;
}
…并且类似于setCell
。这就展开了初始化。当然,这意味着事情会稍微慢一点,尽管这不太可能有明显的区别
阵列克隆
如果不这样做,另一种选择是创建4000插槽阵列一次,然后克隆它,而不是手动创建,希望在JavaScript引擎中完成工作比自己完成实际循环更快:
// ...
var the4k = [];
// ...build it...
// Now use it for one row and clone it for the others
cellInfo[hlim] = the4k;
for ( i = hlim - 1; i; i--) {
cellInfo[i] = the4k.slice(0);
}
阵列克隆对我来说,Chrome从~780ms到~130ms,IE9从~530ms到~50ms
另一个要考虑的问题是,在IE8和更早的时候,“慢脚本警告”不是基于时间,而是基于操作的数量。你的小提琴在IE8上给了我慢脚本警告。我的没有
IE8支持lazy init,因为即使是我的fiddle版本也需要9秒的运行时间。这给了我200毫秒,这给了我在Chrome中不到100毫秒的时间:另一个(过早的)优化可能是使cellInfo[i]成为一个局部变量,所以它在内部循环中没有被查询4000次。这给了我200ms,在Chrome中不到100ms:另一个(过早的)优化可能是使cellInfo[i]成为一个局部变量,所以它在内部循环中没有被查询4000次。顺便说一句,这不是魔术,它只是移动了真正的工作。然后,您将支付与op当前预付相同的性能。为了获得真正的性能,可能应该使用类型化数组。@Esailija:有趣的信息。当然,基于这个答案,这可以解释Chrome的一些速度提升。我不相信IE9会是这样。但任何时候我都可以将一个循环从JavaScript用户区移动到引擎的内部,我称之为win.:-)IE8似乎将
切片计算为一个操作,而不是4000-20000,因此……有趣的是,对于类型化数组克隆,我在google chrome中的运行时间为3ms。无需考虑,子阵列
与slice@Esailija字体和我的7。对于原始阵列克隆,在780ms或非类型阵列克隆方面有一点进步。美好的当然,类型化数组是非常新的,甚至在IE9中也没有(尽管我注意到它们似乎出现在最新的Firefox和Opera中!)。非常感谢T.J!我有一个想法,我可以以某种方式使用已经生成的数据,但不知道如何使用。感谢Esailija,感谢您对类型化数组的精彩评论!顺便说一句,这不是魔术,它只是移动真正的工作。然后,您将支付与op当前预付相同的性能。为了获得真正的性能,可能应该使用类型化数组。@Esailija:有趣的信息。当然,基于这个答案,这可以解释Chrome的一些速度提升。我不相信IE9会是这样。但任何时候我都可以将一个循环从JavaScript用户区移动到引擎的内部,我称之为win.:-)IE8似乎将切片计算为一个操作,而不是4000-20000,因此……有趣的是,对于类型化数组克隆,我在google chrome中的运行时间为3ms。无需考虑,子阵列
与slice@Esailija字体和我的7。对于原始阵列克隆,在780ms或非类型阵列克隆方面有一点进步。美好的当然,类型化数组是非常新的,甚至在IE9中也没有(尽管我注意到它们似乎出现在最新的Firefox和Opera中!)。非常感谢T.J!我有一个想法,我可以以某种方式使用已经生成的数据,但不知道如何使用。感谢Esailija,感谢您对类型化数组的精彩评论!