Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/421.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript JS中700毫秒内的800万次迭代可以吗?如何加速?_Javascript_Performance - Fatal编程技术网

Javascript JS中700毫秒内的800万次迭代可以吗?如何加速?

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

我有一个游戏和初始化地图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.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,感谢您对类型化数组的精彩评论!