2016-07-28 29 views
0
for (var key in obj) { 
    if (key.indexOf(str) >= 0) { 
     delete obj[key] 
    } 
} 

说你的对象开始变得非常大,例如10,000键,你需要开始思考规模。有什么方法可以加快速度?如何优化通过具有大量键的对象的循环,删除包含给定字符串的键?

+0

不,不是真的,不是*不*使用与10K键的对象等。 – adeneo

+2

如果你知道可能的数量,你可以从objA删除密钥或者只是创建一个新的objB,并添加不会被屏蔽掉的密钥。仍然没有留下为什么你期望一个10k的关键物品袋的问题。 –

+1

'Object.keys(o).filter(/./。test,/str/).forEach(k=>delete o [k])'_might_可以更快,或者至少可以通过分解操作来扩展 – dandavis

回答

2

以下是使用两种方法进行的性能测试。事实证明,不同浏览器的结果差别很大。

在我的方框中,原始对象中的删除键(方法#1)在Firefox中显着较慢,边缘稍慢,Chrome稍快。

另一方面,创建一个新对象(方法#2)在所有浏览器上运行时间相似,速度相当快。所以,我认为这个第二种方法应该是有特权的。

测试对象平均包含50%的匹配键,所以测试对于这两种方法都应该是公平的。

var n, ts, obj, str = "abc"; 
 

 
// creating an object with 10000 keys 
 
for(n = 0, obj = {}; n < 10000; n++) { 
 
    obj["key" + n + (Math.random() < 0.5 ? str : '')] = Math.random(); 
 
} 
 

 
// applying method #1 
 
ts = performance.now(); 
 

 
for(var key in obj) { 
 
    if(key.indexOf(str) >= 0) { 
 
    delete obj[key] 
 
    } 
 
} 
 

 
console.log('Method #1 : ' + (performance.now() - ts).toFixed(2) + 'ms'); 
 

 
// creating an object with 10000 keys 
 
for(n = 0, obj = {}; n < 10000; n++) { 
 
    obj["key" + n + (Math.random() < 0.5 ? str : '')] = Math.random(); 
 
} 
 

 
// applying method #2 
 
ts = performance.now(); 
 

 
var newObj = {}; 
 

 
Object.keys(obj).filter(function(key) { 
 
    return key.indexOf(str) == -1; 
 
}).forEach(function(key) { 
 
    newObj[key] = obj[key]; 
 
}); 
 

 
console.log('Method #2 : ' + (performance.now() - ts).toFixed(2) + 'ms');

+0

这并不奇怪。如果密钥集合是一个简单的列表,那么删除一个将导致所有其他的向上移动。所以删除一个密钥就成了O(n)操作。在拷贝之前不必删除多于一个或两个键就变得非常有吸引力。 –

+0

只是挑剔,你应该真的减去'performance.now()',而不是'Date.now()'。考虑到这只有3-5ms长,所以只需调用'.indexOf()'和定时函数'.now()'就可能会产生大量的开销。您应该增加被操作的键的数量,并讨论迭代字符串而不是执行散列表查找来检查每个键是否有效的性能问题。 –

+0

@PatrickRoberts感谢您提供'performance.now()'建议。这已更新。不过,我认为我不应该在可运行的低端设备上运行这个可运行示例中放置太多迭代。我会把它留给读者的主动。 – Arnauld

相关问题