Javascript 性能-我应该同时使用数组和对象来处理庞大的列表吗?

Javascript 性能-我应该同时使用数组和对象来处理庞大的列表吗?,javascript,arrays,performance,object,Javascript,Arrays,Performance,Object,到目前为止,我的服务器已经处理了大量实体的数组 主要是,它每秒对实体执行for循环x次,通过执行实体inscope.indexOf(entity),检查一个实体是否在另一个实体的范围内(每个实体都有一个数组entitiesInScope),这是我程序的最大成本 for (var i = 0; i < entities.length; i++) { var entity = entities[i]; for (var j = 0; j < entities.length

到目前为止,我的服务器已经处理了大量实体的数组

主要是,它每秒对实体执行for循环x次,通过执行实体inscope.indexOf(entity),检查一个实体是否在另一个实体的范围内(每个实体都有一个数组entitiesInScope),这是我程序的最大成本

for (var i = 0; i < entities.length; i++) {
    var entity = entities[i];
    for (var j = 0; j < entities.length; j++) {
        var checkEntity = entities[j];
        var idx = entity.entitiesInScope.indexOf(checkEntity);
        if (idx >= 0) {
            if (!check(checkEntity.state, entity.state)) {
                entity.removeEntityInScope(idx);
                //... remove: send checkEntity.id
            } 
        } else {
            if (check(checkEntity.state, entity.state)) {
                entity.addEntityInScope(checkEntity);
                //... add: send checkEntity.id, checkEntity.state
            }
        }
    }
}
for(变量i=0;i=0){
如果(!check(checkEntity.state,entity.state)){
实体移除实体范围(idx);
//…删除:发送checkEntity.id
} 
}否则{
if(检查(checkEntity.state,entity.state)){
实体。附加检查范围(检查实体);
//…添加:发送checkEntity.id,checkEntity.state
}
}
}
}
(我优化了它,没有对所有实体进行第二次循环,但这不是重点)

但是,我已经看到对象的hasOwnProperty比indexOf更重要。另一方面,我也做了大量的推送和拼接。因此,如果我添加实体对象,我也应该使用delete(perf?)

我应该:

-添加一个id为entity key的对象,以使用hasOwnProperty(entity.id),如果为true,则允许使用indexOf

-添加一个具有实体键的对象,以使用hasOwnProperty(entity.id)(内存浪费)


-继续使用数组

我建议迭代entitiesInScope以更新或删除其中的实体,因为您已经知道这种方式的索引,如果您向后遍历它,则可以删除项目而不会弄乱索引

至于添加缺少的实体,我会在对象中标记entitiesInScope上已经存在的实体,以便快速查找,然后迭代实体并添加缺少的实体。代码与此类似:

for (var i = 0; i < entities.length; i++) {
    var entity = entities[i];
    var alreadyInScope = {}

    for (var j = entity.entitiesInScope.length - 1; j >= 0; j--) {
        var checkEntity = entity.entitiesInScope[j];

        if (!check(checkEntity.state, entity.state)) {
           var id = entity.entitiesInScope.splice(j, 1).id
        } else {
            alreadyInScope[checkEntity.id] = true;
        }
    }

    for (var j = 0; j < entities.length; j++) {
        if (alreadyInScope.hasOwnProperty(entities[j].id) == false) {
            entity.entitiesInScope.push(entities[j])
        }
    }

}
for(变量i=0;i=0;j--){
var checkEntity=entity.entitiesInScope[j];
如果(!check(checkEntity.state,entity.state)){
var id=entity.entitiesInScope.splice(j,1).id
}否则{
AlreadyScope[checkEntity.id]=true;
}
}
对于(var j=0;j
为什么不遍历entitiesInScope数组而不是第二个循环?或者一个映射?()@juvian事实上,有一个物理循环更新实体的状态(位置,…),还有一个广播循环(以前的代码),其中每个实体的entitiesInScope都会更新(添加/删除),通过做一些检查。@Miyud在这种情况下,使用对象而不是数组,并使用hasOwnProperty+delete将更加有效。但仅仅是在范围内穿越实体就更好了。。。(您需要向后遍历它才能在不破坏索引的情况下删除)让我们来吧。谢谢。我想你的意思是删除最后一个元素。顺便说一句,正向拼接(j,1)的性能有差异吗?还是仅仅为了方便用户?@Miyud我错了,拼接(j,1)是正确的option@Miyud如果您在AlreadyScope中有许多实体,并且通常删除10个以上,将您不会删除的内容添加到临时数组中,并在循环结束时用临时数组替换AlreadyScope,可能会更有效