我在HTML5游戏中有一个包含粒子(火,血,烟等)的数组。所有颗粒都具有有效期/寿命。我每帧以60fps创建多达100个粒子,所以我希望尽可能保持这个阵列的清洁,这样我就可以有效地循环它。
我听说使用&#c; splice'而不是删除'从数组中删除元素。这对我来说很有意义,因为我不想循环通过空白的数组键(删除'留下)。
然而,我测试了这一点,并且如果我删除'那么帧速率会更高,更一致。键而不是拼接它们以去除过期的粒子。缺点是游戏运行的时间越长,我的粒子阵列就越长。
有更好的解决方案吗?
答案 0 :(得分:4)
如果数组中项目的顺序无关紧要,则只需将数组中的最后一项指定给要覆盖的项目,然后通过缩小.length
将其删除。
function unordered_remove(arr, i) {
if (i <= 0 || i >= arr.length) {
return;
}
if (i < arr.length - 1) {
arr[i] = arr[arr.length-1];
}
arr.length -= 1;
}
这要快得多,因为它不需要重新索引,并且适用于顺序无关紧要的情况。
答案 1 :(得分:2)
在数组元素上使用delete
时,您实际所做的就是将该数组元素设置为undefined
。该数组仍将具有相同的长度。当您使用splice
时,您实际上完全删除了该元素。该元素被删除,并且该元素之后的所有内容都向下移动1个索引。对于这两个元素,delete
将更快,因为您的数组不必重新索引。
至于性能,如果将已删除的元素保留为undefined
,那么这可能是最好的方法。如果您担心数组长度增长太长,或者可能需要经常搜索该数组并希望减少开销,您可以定期filter
出未定义的元素,如下所示:
function filterArr() {
myArr = myArr.filter(function(v) {
return typeof v !== 'undefined';
});
}
var interval = setInterval(filterArr, 5000);
这将为您提供两全其美的体验。当您需要移除粒子时,可以使用delete
将元素设置为undefined,这比在适当位置移除它们更快。你不时地将它们移除,以保持阵列尺寸更小。
您可以根据自己的要求进行改进。祝你好运:)
答案 2 :(得分:1)
通过自己打包数组,您将获得更高的性能:更少的操作,无需处理当前数组并创建新数组(如Array.filter所做的那样),因此垃圾收集更少。
function packArray(tgtArray) {
if (!tgtArray || !tgtArray.length) return;
var srcIndex = 0;
var dstIndex = 0;
var arrayLength = tgtArray.length ;
do {
var currentItem = tgtArray[srcIndex];
if (currentItem.alive) {
if (srcIndex != dstIndex) {
tgtArray[dstIndex] = currentItem ;
}
dstIndex++;
}
srcIndex++;
} while (srcIndex != arrayLength) ;
dstIndex--;
tgtArray.length = dstIndex > 0 ? dstIndex : 0 ;
}