Javascript数组查找效率:关联与存储关联?

时间:2011-05-04 19:12:15

标签: javascript arrays performance

我一直在阅读,他们说联想数组不会给你与数组相同的效率。关联数组可以在O(N)时间内查找,其中数组可以在O(1)中查找。

这是我的问题:在快速查找值并且不会占用太多内存方面哪一个会更有效率?

关联:

var myVars=new Array(); 
myVars['test1'] = a;
myVars['test2'] = b;
myVars['test3'] = c;
... (up to 200+ values)

echo myVars['test2'];

存储关联:

var myVars=new Array(); 
var TEST1 = 1;
var TEST2 = 2;
var TEST3 = 3;
... (up to 200+ values)

myVars[TEST1] = a;
myVars[TEST2] = b;
myVars[TEST3] = c;
... (up to 200+ values)

echo myVars[TEST2];

4 个答案:

答案 0 :(得分:10)

首先,Array的第一次使用是错误的。尽管可能这样做,但这并不意味着你应该这样做。你正在“滥用”数组也是对象的事实。这可能导致意外行为,例如:虽然您添加了200个值,但myVars.length将为0

不要将JavaScript数组用作关联数组。使用普通对象:

var myVars = {}; 
myVars['test1'] = a;
myVars['test2'] = b;
myVars['test3'] = c;

其次,在JavaScript中,两者(对象和数组)之间没有真正的区别。数组扩展对象并添加一些行为,但它们仍然是对象。元素存储为数组的属性。

您可以在specification

中找到更多信息
  

Array对象对某类属性名称进行特殊处理。当且仅当ToString(ToUint32(P))等于P且ToUint32(P)不等于2 32 时,属性名P(以String值的形式)是数组索引。 -1。 (...)

所以两者:

var obj = {'answer': 42};
obj['answer'];

var arr = [42];
arr[0];

具有相同的访问时间,这绝对是 O(n)

†:最好说应该。显然,这在不同的实现中有所不同。


除此之外,你的第二个例子很难维护。如果为变量分配数字,为什么不直接使用数字?

var myVars = []; 
myVars[0] = a;
myVars[1] = b;
myVars[2] = c;

<强>更新

更重要的是:您必须根据需要选择正确的数据结构,这不仅取决于单个元素的访问时间,还取决于:

  • 键是连续数字还是任意字符串/数字?
  • 您是否必须访问集合中的所有元素(即遍历所有元素)?

数值数组(数组)和关联数组(或哈希表/地图(JS中的对象))为不同的问题提供不同的解决方案。

答案 1 :(得分:3)

我认为目前的答复没有充分考虑更实际的用例。我创建了this jsperf to demonstrate。虽然@Felix的jsperf demonstrates lookup speed,但它并没有在足够大的对象上执行才真正有用。我认为10,000个简单属性更合理。此外,您需要随机选择序列中的键进行读取,修改,删除和创建,以真正演示两种类型之间的性能差异。

答案 2 :(得分:2)

首先,无论他们是谁,都可以随意忽略它们。

每个体面的脚本语言(包括JavaScript)的每个体面实现都会为您提供O(log(n))访问时间的关联数组,或O(1)平均访问时间,O(n)最坏情况(你几乎从未打过它。无论哪种方式,实际上查找都很快。

阵列具有O(1)保证的访问时间,这非常快。但是在某些脚本语言(例如PHP)中,甚至没有提供本机数组类型。他们只使用关联数组。

答案 3 :(得分:0)

答案:test it out yourself

更新:在与Felix进行一些反复之后,看起来数组访问通常比关联数组和对象都快。情况并非总是如此,特别是在Chrome中。在Ubuntu 11上的Chrome 11中,阵列速度更快。在Mac OS 10.6上的Chrome 11中,它们之间没有显着差异。

这些测试并未测量操作,只是读取。