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

Javascript数组查找效率:关联与存储关联?,javascript,arrays,performance,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

我一直在读,他们说关联数组不能提供与数组相同的效率。关联数组可以在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];

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

不要将JavaScript数组用作关联数组。使用普通对象进行以下操作:

var myVars = {}; 
myVars['test1'] = a;
myVars['test2'] = b;
myVars['test3'] = c;
其次,在JavaScript中,两者(对象和数组)之间没有真正的区别。数组扩展对象并添加一些行为,但它们仍然是对象。元素作为数组的属性存储

您可以在以下目录中找到更多信息:

数组对象对某类属性名给予特殊处理。当且仅当ToString(ToUint32(P))等于P且ToUint32(P)不等于232时,属性名P(以字符串值的形式)才是数组索引−1.(……)

因此,两者:

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

具有相同的访问时间†,这肯定是而不是
O(n)

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


除此之外,您的第二个示例很难维护。如果给变量赋值,为什么不直接使用这些数字呢

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

更新:

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

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

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

首先,不管是谁,都可以忽略它们

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

阵列具有O(1)保证的访问时间,这是难以置信的快。但在某些脚本语言(如PHP)中,甚至没有提供本机数组类型。它们只是对两者都使用关联数组。

答案:。

更新:在与Felix进行了一些往返之后,似乎数组访问通常比关联数组和对象都快。情况并非总是如此,尤其是在Chrome中。在Ubuntu11上的Chrome11中,阵列速度更快。在MacOS10.6上的Chrome11中,它们之间没有明显的区别


这些测试并没有测量操作,只是测量读数

>我认为目前的反应没有充分考虑更多的实际使用情况。我创造了。虽然@Felix是,但它并没有在足够大的对象上执行,因此无法真正发挥作用。我认为10000个简单的属性更合理。此外,您需要在序列中随机选择要读取、修改、删除和创建的键,以真正演示这两种类型之间的性能差异。

FWIW Javascript中没有类似于。。。只是一个具有类似访问过程的对象。自己测试性能:或者这个:@Felix您的测试对他的特定问题不现实。看我的测试。它与你的相反。此外,您的对象和阵列访问测试也没有经过深思熟虑。你不是在比较苹果。还有另一个测试,你确定这是错的吗?我不是JavaScript程序员,但我的理解是JavaScript
数组
是一种
对象
,因此可以像其他任何对象一样使用。这样做是令人困惑的,但从技术上讲并不是不正确的。@btilly:这是错误的,因为它令人困惑。我不是说技术上错了。例如,如果以这种方式分配值,
arr.length
仍将是
0
。将澄清我的答案…@b直到你想迭代你的散列并最终得到所有数组的方法。当然,你也可以解决这个问题,但如果有一个更干净、更普通的容器,那就不需要做任何工作了。对不起,我应该解释得更清楚一些。我有不止一个这样的存储设备,为每一个设备都有一个查找表是相当烦人的。理想情况下,我更愿意在我的代码中看到myVars['test1'],而不是myVars[23],尤其是当我有几个myVars要查看时。我同意更新。然而,这里有一个性能测试:Javascript也没有正确的数组,它们是伪造的。当前数组实现中的查找时间与对象属性查找时间相同。@Alnitak:JavaScript数组支持shift。这对我来说意味着有两种不同的查找机制,因为使用关联数组支持shift将是一件痛苦的事情。这是一件痛苦的事情——每当您这样做时,大多数实现都必须对所有现有的键重新编号!请参阅(不是我的)以了解pop与shift的比较。在较旧的浏览器上预处理速度慢1000倍。只有Chrome和IE9.0在数组上具有O(1)类型的性能。Chrome中似乎有一些包含数字的字符串作为对象属性。如果您使用“普通”字符串,两者的性能都相同:@LeviMorrison:您必须小心。您仍然将数组
[]
用作“关联数组”。您应该改用对象。根据规范,我假设每当在数组上设置属性时,该属性都是
var myVars = []; 
myVars[0] = a;
myVars[1] = b;
myVars[2] = c;