Javascript 性能-我应该同时使用数组和对象来处理庞大的列表吗?
到目前为止,我的服务器已经处理了大量实体的数组 主要是,它每秒对实体执行for循环x次,通过执行实体inscope.indexOf(entity),检查一个实体是否在另一个实体的范围内(每个实体都有一个数组entitiesInScope),这是我程序的最大成本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 (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,可能会更有效