jquery.inArray()和Object.hasOwnProperty()之间的性能差异是什么?

9

我有一个情况,可以选择将字符串键的集合实现为对象:

$.each(objects, function (key, object) {
    collection[key] = "doesn't matter";
});

或者一个数组:
$.each(objects, function (key, object) {
    collection.push(key);
});

我希望能够快速确定集合中是否包含给定的键。如果集合是一个对象,我可以使用以下方法:

if (collection.hasOwnProperty(key_to_find)) { // found it!... }
else { // didn't find it... }

如果集合是一个数组,我可以使用以下代码:
if ($.inArray(key_to_find, collection)) { // found it!... }
else { // didn't find it... }

我认为使用JavaScript内置的hasOwnProperty比jQuery的inArray()更快,但我不完全确定。有没有人了解这两种方法之间的性能差异?或者,是否有更有效的替代方案我不知道?


这里的另一个考虑因素就是空间:我假设对象可以比数组稍微小一些,因为对象和数组中的键字符串将是相同的,而且对象可以有一个8位字符(只有一个字符)作为每个键参数的值,而不是与数组中每个键关联的32位指针。这些假设可能完全错误:)我会感激任何指向这些东西在各种平台上(例如浏览器、机器等)如何存储的指针。 - Gaurav
密钥集有多大?如果很小,那么不应该有太大的差异。如果很大,对象的恒定访问时间(或者说“快速”)将会更快。 - Cristian Sanchez
5个回答

7
如果我们只谈论检查所需时间的话,那么就没有什么比较了:http://jsperf.com/array-vs-obj。由于其它人所述的原因,hasOwnProperty 要快得多。

1
使用 obj['key']hasOwnProperty() 更快。此外,可以使用 true 作为添加的值,而不是 "doesn't matter" - Dan Manastireanu
好观点。通常我也是这样做的,但没有想到要检查它,只是从问题中提取了代码。 - James Montagne
谢谢 - 我不知道如果键不存在,obj['key'] 不会抛出未定义属性错误。只要我们确定对象存在,JS 是否正确地对存在(true)或不存在(false)的对象参数进行评估? - Gaurav
那个测试在我的浏览器中显示相反的结果。也许自2011年以来JS引擎已经得到了改进? - Mister Smith
哎呀,不是这样的。有人把结果表中的标签放错了位置,标记为“array”的实际上是测试对象 :) - Mister Smith

1

3
如此stackoverflow文章所述,Array.indexOf()在所有浏览器中均不支持,因此使用jQuery.inArray()。根据@kingjiv提供的性能测试,Object.hasOwnProperty()比jQuery.inArray()快得多。 - Gaurav

1

数组方法较慢,因为需要线性时间在数组中查找元素(代码必须遍历可能的每个元素)。hasOwnProperty会更快,因为它可以使用哈希表查找,这发生在常数时间内。


1

对象的属性访问速度非常快。但是,您仍然必须考虑从计算哈希等方面产生的开销(如果实现使用哈希表来支持对象)。如果键集相对较小,则不应该有太大的差别。如果它更大,则我将使用对象 /哈希来存储属性。

话虽如此,使用对象可以更轻松地管理重复的键,因此我个人会选择字典。

除非这是您的应用程序的瓶颈,否则不应过于担心。


0

这里的结果是以秒为单位的吗? - Musikero31
@Musikero31 应该是毫秒。Charlino,你的性能测试非常简单,而且不太准确。对于这么小的集合,任何用于确定项目是否存在于集合中的算法都会返回相对相同的结果。只有当你扩大集合的规模时,相对性能才真正发挥作用。 - Nick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接