有效地计算 JavaScript 中对象的键/属性的数量
Posted
技术标签:
【中文标题】有效地计算 JavaScript 中对象的键/属性的数量【英文标题】:Efficiently counting the number of keys / properties of an Object in JavaScript 【发布时间】:2011-12-18 21:13:53 【问题描述】:这个问题与How to efficiently count the number of keys/properties of an object in javascript?几乎相同。
我想知道一条额外的信息:什么是“恒定时间”确定对象中键数量的方法?我最关心的是在 Node.JS 中执行此操作,因为浏览器上的大多数对象都不会太大而不会引起很大的关注。
编辑:
在 Google Chrome 和 Node.JS 中,Object.keys(obj).length
似乎以线性时间 O(n) 返回(即取决于obj
中的键数)。有没有更好的 O(1) 方法?
我在 Node.JS 中做了一些测试(来源如下)
var tests = [10e3, 10e4, 10e5, 10e6]
for(j in tests)
var obj = ;
for(i = 0; i < tests[j]; i++)
obj[i] = i;
console.time('test' + tests[j]);
Object.keys(obj).length;
console.timeEnd('test' + tests[j]);
对于 n = 10e3, 10e4, 10e5, 10e6... 结果是:
test10000: 5ms
test100000: 20ms
test1000000: 371ms
test10000000: 4009ms
【问题讨论】:
不。我今天感觉很懒惰......:/星期一的情况,我想。 我怀疑从调用“Object.keys()”的结果中获取“.length”是常数时间,但我也怀疑调用“Object.keys()”是线性的属性的数量。 jsperf.com/object-keys-performance 100 倍于对象中的项目导致它在 Chrome 上的速度是 200 倍。 谢谢,@pimvdb -- 这真是个令人难过的消息。 :( Node.JS 中是否有任何常量时间键计数方法? @BMiner 对不起,我的意思是,Object.keys(o).length
是 O(n)。数组上的.length
是 O(1)。
【参考方案1】:
经过一番研究,没有办法在恒定时间内确定 JavaScript 对象中键的数量,至少在 Node 中没有……而且目前还没有。 Node 内部会跟踪这些信息,但不会公开它,因为在 ECMA-262 5th 中没有这样做的方法。
值得注意的是,Harmony(ECMA 版本 6)可能原生支持 Maps 和 Sets。不确定这些的规格会是什么。
有人告诉我,我们需要向 TC39 委员会提出这个问题。
V8 的错误报告:http://code.google.com/p/v8/issues/detail?id=1800
【讨论】:
【参考方案2】:ECMA 6 Harmony 引入了 Map
和 Set
类,您可能会使用它们(将来:)
var map = new Map;
map.set('a', 'b');
console.log(map.size); // prints 1
我相信它应该具有 O(1) 的复杂度,但没有尝试过。您可以通过node --harmony script.js
在节点 0.11+ 中运行它。
另一种方法是使用Proxy
类,该类也已添加到harmony中。
【讨论】:
【参考方案3】:查看源代码,特别是GetLocalElementKeys
v8 objects.cc
【讨论】:
我懒得做这个了。请用英语。我很乐意接受你的回答。 :P 根据对象包含的内容,它们会做不同的事情,最坏的情况似乎是 1 for 循环遍历所有元素。以上是关于有效地计算 JavaScript 中对象的键/属性的数量的主要内容,如果未能解决你的问题,请参考以下文章