Javascript中的Object vs Arrays是Python的Dictionaries vs Lists吗?

时间:2014-03-14 20:13:11

标签: javascript python performance

我知道在python中我可以使用列表来快速排序和字典,以便更快地搜索事物(因为可以对不可变对象进行哈希处理)。对于javascript也一样吗?经过多次搜索后,我还没有看到关于javascript中数据类型性能的任何信息。

2 个答案:

答案 0 :(得分:0)

是。 “Javascript中的对象与数组是Python的字典与列表”。 性能优劣也是一样的。如果数字索引适合于任务,则列表更有效,并且字典对于必须由字符串访问的长列表更有效。

var dict = {};
dict['apple'] = "a sweet edible fruit";
dict['boy'] = "a young male human";

var list = [];
list.push("apples");
list.push("oranges");
list.push("pears");

答案 1 :(得分:0)

我一直在寻找可以回答这个问题的书目和其他资料。我知道这不是最佳答案,但让我尝试一个涉及一些概念的答案,以便我们讨论此主题。

Javascript和继承

尽管它可能暗示javascript中的数组和对象就像列表和字典,但它们是不同的,因为每种语言以不同的方式编写,具有不同的基本哲学,概念和目的。

就Java语言而言,似乎Arryas和Objects更像是哈希表。与直觉相反,数组只是javascript的另一种内置对象。实际上,正如他们在ECMAScript Specification 6.1.7

中所说的那样
  

对象类型

     

从逻辑上讲,对象是属性的集合。每个属性是   数据属性或访问器属性:

     

数据属性将键值与ECMAScript语言相关联   值和一组布尔属性。访问者属性关联   具有一个或两个访问器函数的键值,以及一组布尔值   属性。访问器函数用于存储或检索   与属性关联的ECMAScript语言值。   使用键值标识属性。属性键值为   ECMAScript字符串值或符号值。所有字符串和   符号值(包括空字符串)可以用作属性键。   属性名称是作为字符串值的属性键。

     

整数索引是一个字符串值的属性键,它是规范的   数字字符串(请参见7.1.16),其数字值为+0或a   正整数≤253-1。数组索引是其整数索引   数值i的范围为+0≤i <232-1。

     

属性键用于访问属性及其值。那里   属性的两种访问方式:get和set,对应于   值检索和赋值。属性   通过获取和设置访问权限可访问,包括自己的属性   是对象的直接部分,继承的属性是   由另一个关联的对象通过属性继承提供   关系。继承的属性可以是自己的,也可以是继承的   关联对象的属性。对象的每个属性   必须每个都有一个与   该对象的其他自身属性。

然后about the arrays,它指定:

  

22.1Array对象

     

数组对象是特殊对象,它们对某些类的属性名称给予特殊对待。

按照上面的逻辑,以及在规范中所说的那样,该语言被认为是javascript中的所有类型都扩展了一个全局对象,然后添加了新的方法和属性以具有不同的行为。

内存管理

语言规范和在实际运行时环境中必须如何实现之间存在差距。尽管每种实现都有自己的逻辑,但似乎大多数逻辑都有相似之处。

This Article Explains

  

大多数JavaScript解释器使用类似字典的结构(哈希   基于函数)将对象属性值的位置存储在   记忆。这种结构使得可以检索以下属性的值:   JavaScript在计算上比在JavaScript中更昂贵   非动态编程语言,例如Java或C#。在Java中,所有   对象属性由固定的对象布局决定,   编译,并且无法在运行时动态添加或删除   (好吧,C#具有动态类型,这是另一个主题)。结果是,   属性的值(或指向这些属性的指针)可以是   作为固定缓冲区存储在内存中的连续缓冲区   彼此之间。偏移的长度可以很容易地根据   属性类型,而这在JavaScript中是不可能的   属性类型可以在运行时更改。

由于这会使javascript变得毫无效率,工程师不得不采用一些巧妙的解决方法来解决此问题。跟随this other article

  

如果您访问属性,例如object.y,JavaScript引擎看起来   在JSObject中输入键“ y”,然后加载相应的属性   属性,最后返回[[Value]]。

     

但是这些属性属性存储在内存中的什么位置?我们应该吗   将它们存储为JSObject的一部分?如果我们假设我们会看到   以后再有更多具有此形状的对象,那么存储   完整的字典,其中包含属性名称和属性   JSObject本身,因为对所有对象重复属性名称   具有相同的形状。重复很多,不必要地   内存使用情况。作为优化,引擎会存储   单独对象。

     

此Shape包含所有属性名称和属性,但   为他们的[[Value]]。而是Shape包含了   JSObject内部的值,以便JavaScript引擎知道   在哪里找到值。每个具有相同形状的JSObject都指向   精确到此Shape实例。现在每个JSObject只需要存储   该对象唯一的值。

     

当我们有多个对象时,好处显而易见。不管怎样   有很多物体,只要它们具有相同的形状,我们就   必须一次存储形状和属性信息!

     

所有JavaScript引擎都使用形状作为优化,但它们没有   都称它们为形状:

     
      
  • 学术论文称它们为“隐藏类”(令人困惑的JavaScript类)
  •   
  • V8称它们为Maps(令人困惑的JavaScript Maps)
  •   
  • Chakra称它们为Types(混淆了JavaScript的动态类型和typeof)
  •   
  • JavaScriptCore称它们为结构   * SpiderMonkey称它们为Shapes
  •   

Python

数组

Python使用不同的方法来实现列表,列表似乎更像是一些动态数组,而不是在C中可以找到的实际数组,但是它们始终专注于节省时间和复杂性。运行。 As this FAQ cited form the PyDocs says

  

Python的列表对象实际上是变长数组,而不是   Lisp样式的链表。该实现使用一个连续数组   引用其他对象,并保持指向该数组和   列表头结构中数组的长度。

     

这使索引列表(L [i])的操作成本为   与列表的大小或索引的值无关。

     

在添加或插入项目时,引用数组为   调整大小。运用一些技巧来提高性能   重复添加项目;当数组必须增长时,一些额外的   已分配空间,因此接下来的几次不需要实际   调整大小。

像javascript一样,Python的列表也不要求是同质的,因此它们并不是其他“强类型”数据结构的实际实现,这些数据结构只必须包含相同的实体,例如整数,字符串等。

与javascript一样,语言的规范实际实现是两件事。取决于您是否使用Cpython,Jython,IronPython等,在将python解释为机器代码的过程中,内存管理和在后台运行的实际功能将产生不同的作用。

我知道这不是最好的来源,但是as I found discussed in Quora

  

与其名称含义相反,Python列表实际上是数组(...)。   具体来说,它们是具有指数的动态数组   过度分配,这使得如下代码具有线性   复杂性:

lst = []
for i in xrange(0, 100000):
    lst.append(i)
     

Jython和IronPython之类的替代实现似乎使用了   任何本地动态数组类及其底层语言   (分别是Java和C#)提供的,因此它们具有相同的性能   特性(精确的基础类似乎是ArrayList   Jython和IronPython的C#列表)。

     

(...)数组在技术上存储指针而不是对象   本身,从而允许数组仅包含   具体尺寸。在底层的各处都有指针   实现是动态类型语言的共同特征,并且   实际上,任何试图假装的语言都没有   指针。

字典

如官方文档在其"History and Design FAQ"中所述

  

CPython的字典被实现为可调整大小的哈希表。   与B树相比,这为查找提供了更好的性能(   在大多数情况下,是迄今为止最常见的操作),并且   实施比较简单。

     

字典的工作方式是为存储在   使用hash()内置函数的字典。哈希码有所不同   广泛取决于密钥;例如,“ Python”哈希   -539294296,而“ python”(一个相差一个位的字符串)则散列为1142331976。然后使用哈希码来计算   内部数组中将存储值的位置。假设   您存储的键都具有不同的哈希值,   表示字典需要固定的时间–计算机科学中的O(1)   表示法–检索密钥。这也意味着没有排序顺序   键被保留,并以.keys()和   .items()do将以任意方式输出字典的内容   混乱的订单。

结论中

关于语言,有两件事:一件事涉及语言的工作方式,语法,语义,逻辑和哲学。另一方面,您可以在特定的运行时,解释器或编译中实际实现该语言。 这样,尽管(理论上)您拥有一个Python或一个Javascript,但是您可以拥有CPython,IronPython Jython等。另一方面,您有SpiderMonkey,V8等。

但是,在谈到每个运行时如何实现数组/列表和对象/字典的语言功能以及它们的相似性时,似乎Javascript选择了基于原型的继承模型,使原型成为一种对象。因此对象和字典都更像是哈希表,而不是实际的数组。 另一方面,Python在数据结构方面具有更多的特色,无论是在其库中还是在解释器如何处理它们方面,都使用数组或动态数组使Pyton's Lists变得栩栩如生,并使用哈希表字典,使它们与javascript中的对象更加相似。