Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/420.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何优化具有大量键的对象的循环,删除包含给定字符串的键?_Javascript_Algorithm - Fatal编程技术网

Javascript 如何优化具有大量键的对象的循环,删除包含给定字符串的键?

Javascript 如何优化具有大量键的对象的循环,删除包含给定字符串的键?,javascript,algorithm,Javascript,Algorithm,假设您的对象开始变得非常大,例如10000个关键点,您需要开始考虑缩放。有什么方法可以加快速度吗?下面是一个使用两种方法的性能测试。结果表明,不同浏览器的结果差别很大 在“我的盒子”中,在Firefox中删除原始对象中的键(方法#1)的速度明显较慢,在Edge中略慢,在Chrome中略快 另一方面,创建一个新对象(方法#2)在所有浏览器上运行的时间都差不多,而且速度相当快。所以,我认为第二种方法应该是有特权的 测试对象平均包含50%的匹配密钥,因此对于这两种方法,测试应该是公平的 变量n,ts

假设您的对象开始变得非常大,例如10000个关键点,您需要开始考虑缩放。有什么方法可以加快速度吗?

下面是一个使用两种方法的性能测试。结果表明,不同浏览器的结果差别很大

在“我的盒子”中,在Firefox中删除原始对象中的键(方法#1)的速度明显较慢,在Edge中略慢,在Chrome中略快

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

测试对象平均包含50%的匹配密钥,因此对于这两种方法,测试应该是公平的

变量n,ts,obj,str=“abc”; //创建具有10000个关键点的对象 对于(n=0,obj={};n<10000;n++){ obj[“key”+n+(Math.random()<0.5?str:'')=Math.random(); } //应用方法#1 ts=性能。现在(); for(obj中的var键){ if(key.indexOf(str)>=0){ 删除obj[键] } } log('Method#1:'+(performance.now()-ts).toFixed(2)+'ms'); //创建具有10000个关键点的对象 对于(n=0,obj={};n<10000;n++){ obj[“key”+n+(Math.random()<0.5?str:'')=Math.random(); } //应用方法#2 ts=性能。现在(); var newObj={}; Object.keys(obj).过滤器(函数(键){ 返回键indexOf(str)=-1; }).forEach(功能(键){ newObj[key]=obj[key]; });
log('Method#2:'+(performance.now()-ts).toFixed(2)+'ms')是使用两种方法进行的性能测试。结果表明,不同浏览器的结果差别很大

在“我的盒子”中,在Firefox中删除原始对象中的键(方法#1)的速度明显较慢,在Edge中略慢,在Chrome中略快

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

测试对象平均包含50%的匹配密钥,因此对于这两种方法,测试应该是公平的

变量n,ts,obj,str=“abc”; //创建具有10000个关键点的对象 对于(n=0,obj={};n<10000;n++){ obj[“key”+n+(Math.random()<0.5?str:'')=Math.random(); } //应用方法#1 ts=性能。现在(); for(obj中的var键){ if(key.indexOf(str)>=0){ 删除obj[键] } } log('Method#1:'+(performance.now()-ts).toFixed(2)+'ms'); //创建具有10000个关键点的对象 对于(n=0,obj={};n<10000;n++){ obj[“key”+n+(Math.random()<0.5?str:'')=Math.random(); } //应用方法#2 ts=性能。现在(); var newObj={}; Object.keys(obj).过滤器(函数(键){ 返回键indexOf(str)=-1; }).forEach(功能(键){ newObj[key]=obj[key]; });
log('Method#2:'+(performance.now()-ts).toFixed(2)+'ms')不,不是真的,除了不使用具有10k键的对象。如果您知道可能要剥离的键数,您实际上可以在从objA删除键或仅创建新objB和添加不会被筛选的键之间进行性能比较。仍然存在一个悬而未决的问题:为什么您期望一个10k键的对象包。
object.keys(o.filter(/./.test,/str/).forEach(k=>delete o[k])
可能更快,或者至少可以通过分解操作来扩展您的用例吗?任何潜在的优化都需要更多地了解这些对象及其键是如何创建的。在迭代该对象时,您是否已经遇到了真正的问题?可能是一些错误,“挂起”?不,不是真的,除了不使用具有10k关键点的对象。如果您知道可能要剥离多少个关键点,您实际上可以在从objA删除关键点或仅创建新的objB和添加不会被筛选的关键点之间进行性能比较。仍然存在一个悬而未决的问题:为什么您期望一个10k键的对象包。
object.keys(o.filter(/./.test,/str/).forEach(k=>delete o[k])
可能更快,或者至少可以通过分解操作来扩展您的用例吗?任何潜在的优化都需要更多地了解这些对象及其键是如何创建的。在迭代该对象时,您是否已经遇到了真正的问题?也许,一些错误,“绞刑”?这并不奇怪。如果键的集合是一个简单的列表,那么删除其中一个键将导致所有其他键向上移动。因此,删除密钥成为一个O(n)操作。在复制变得非常吸引人之前,不需要删除一个或两个以上的键。只是吹毛求疵,您应该真正减去
performance.now()
,而不是
Date.now()
。考虑到这只有3-5毫秒长,仅调用
.indexOf()
和计时函数
.now()
可能会带来大量开销。您应该增加被操作的键的数量,并讨论由于迭代字符串而导致的性能问题,而不是通过哈希表查找来检查每个键是否有效。@PatrickRoberts感谢您的
performance.now()
建议。这是最新的。不过,我认为我不应该在这个可运行的示例中投入太多的迭代,它可能会在低端设备上执行。我将把它留给读者的主动权。@JimMischel虽然你的分析完美地描述了FIrefox中发生的事情,但结果表明,当删除一个键时,Edge和Chrome都不会移动键。他们可能在使用链表,只是在更新指针。我的最新评论很精确:当进行更多迭代时,结果表明方法1在Firefox中以多项式时间运行(验证delete[]
for (var key in obj) {
    if (key.indexOf(str) >= 0) {
        delete obj[key]
    }
}