Object.keys()复杂性?

时间:2011-10-10 18:04:19

标签: javascript performance time-complexity ecmascript-5

任何人都知道ECMAScript5的Object.keys()在常见实现中的时间复杂度? O(n)密钥是n吗?假设哈希实现,时间是否与哈希表的大小成正比?

我正在寻找语言实现者或某些真实世界基准测试的保证。

2 个答案:

答案 0 :(得分:18)

至少在V8(chrome,node.js)中似乎是O(n)

> var hash = {}
>   ,    c = 0;
> 
> var s = +new Date();Object.keys(hash);console.log(+new Date() - s);
0
> for(var i=0; i<100000; i++, c++){ hash[c] = 1; }
> var s = +new Date();Object.keys(hash);console.log(+new Date() - s);
26
> for(var i=0; i<100000; i++, c++){ hash[c] = 1; }
> var s = +new Date();Object.keys(hash);console.log(+new Date() - s);
49
> for(var i=0; i<100000; i++, c++){ hash[c] = 1; }
> var s = +new Date();Object.keys(hash);console.log(+new Date() - s);
75
> for(var i=0; i<100000; i++, c++){ hash[c] = 1; }
> var s = +new Date();Object.keys(hash);console.log(+new Date() - s);
102    

答案 1 :(得分:5)

(这里是V8开发人员。)

马克·卡恩(Mark Kahn)的答案对于密度足够大的整数键/“索引”属性是正确的,其中Object.keys()的复杂度确实为O(n)。

尽管JavaScript规范假设所有对象属性都是字符串键的/“命名的”,但这并不是现代高性能引擎实现它的方式。内部存在巨大差异!索引属性存储在数组中(只要它们足够密集即可),通常,它们的性能要比{'1': 1, ...}字典更好。

对于具有成千上万个 named 属性的对象,我们的实现确实使用了哈希表(正如猜测的那样),这意味着{strong> Object.keys()的复杂度为O(n log n)。这是因为哈希表(当然)以其自己的顺序存储条目。 Object.keys()必须按照创建它们的顺序返回命名属性,我们将其存储为其他元数据,因此这意味着我们必须在从哈希表中检索键之后对键进行排序,该键为O(n log n )操作。

在实践中大多数对象上的命名属性(最多约一千个属性)通常按创建顺序存储在特殊类型的内部数组中,因此可以在O中进行检索(n),无需排序。

所以摘要实际上是“取决于”的:-)