1

我有一个游戏并初始化一个 2000 x 4000 块的地图。它仅在 onLoad 上运行一次,需要大约 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);​

这是小提琴:http: //jsfiddle.net/NSX9z/

4

1 回答 1

6

几个选项供您选择:

惰性初始化

加快速度的最佳选择是使用延迟初始化。例如,与其初始化所有 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. 这分散了初始化。当然,这意味着事情会稍微慢一些,尽管不太可能有明显的差异。

阵列克隆

如果你不这样做,另一种选择是创建一次 4,000 槽数组,然后克隆它而不是手动创建它,希望在 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 支持惰性初始化,因为即使是我的小提琴版本也需要将近9 秒的时间才能运行。

于 2012-12-04T12:16:28.220 回答