【问题标题】:Are JavaScript Arrays actually implemented as arrays?JavaScript 数组实际上是作为数组实现的吗?
【发布时间】:2012-03-03 06:40:59
【问题描述】:

JavaScript ArrayObject 之间的区别不是很大。其实Array好像主要是增加了length这个字段,所以Arrays和Objects都可以作为数值数组使用:

var ar = new Array();
ar[0] = "foo";
ar["bar"] = "foo";

var ob = new Object();
ob[0] = "foo";
ob["bar"] = "foo";

assert(ar[0] == ob[0] == ar["0"] == ob["0"] == ar.bar == ob.bar); // Should be true.

所以我的问题是,在流行的 JavaScript 引擎中V8、JavaScriptCore、SpiderMonkey 等),这是如何处理的?显然,我们不希望我们的数组实际存储为带有键值的哈希映射!我们如何合理地确定我们的数据存储为一个实际的数组?

据我所知,引擎可以采取几种方法:

  1. Array 的实现方式与 Object 完全相同 - 作为带有字符串键的关联数组。
  2. Array 是一种特殊情况,有一个类似std::vector 的数组支持数字键,如果你这样做ar[100000000] = 0;,还有一些密度启发式以防止疯狂的内存使用
  3. ArrayObject 相同,所有对象都会得到启发,看看使用数组是否更有意义。
  4. 我没有想到的极其复杂的事情。

如果有适当的数组类型,这真的会更简单(咳嗽WebGL类型化数组咳嗽)。

【问题讨论】:

  • 这个article有点老了,没有明确解释实现。但是,它会进行详细的性能测量,并推断可能的实现。
  • 数组不是只是一个带有length属性的地图。如果是,那么移位或取消移位会破坏索引(即,将一个值移出数组,它仍然从索引 0 开始,而不是 1)。所以至少还有一些事情要做。 (当然,这并不一定说明实施的任何内容)
  • 您为什么认为r[0] == ob[0] == ar["0"] == ob["0"] == ar.bar == ob.bar 是真的? 'a' == 'a' == 'a' 为 false,因为它的计算结果为 true == 'a',而 false 的计算结果为。
  • @Flambino,这不是真的。 shift 是作为通用方法实现的,而不是特定于数组的。它适用于常规对象。移位之所以有效,是因为它获取第一个值,然后循环分配给左的所有值,最后删除最后一个元素并设置长度。
  • @Flambino,尝试运行var a = { 0: 0, 1: 1, length: 2 }; Array.prototype.shift.apply(a); alert(JSON.stringify(a))。你应该可靠地得到{"0":1,"length":1}

标签: javascript arrays performance v8 spidermonkey


【解决方案1】:

在 SpiderMonkey 中,数组基本上是作为 jsval 的 C 数组实现的。这些被称为“密集阵列”。然而,如果你开始对它们做类似非数组的事情——比如像对待对象一样对待它们——它们的实现就会变成非常类似于对象的东西。

故事的寓意:当你想要一个数组时,就使用一个数组。当你想要一个对象时,就使用一个对象。

哦,jsval 是一种可变参数类型,它可以表示 64 位 C 类型中任何可能的 JavaScript 值。

【讨论】:

    【解决方案2】:

    在 V8 和 Carakan(可能还有 Chakra)中,所有(非宿主)对象(包括数组和非数组)的属性名称为数组索引(在 ES5 中定义)都存储为密集数组(包含一些值包装器的 C 数组)或稀疏数组(实现为二叉搜索树)。

    统一的对象表示表明它会影响枚举顺序:对于一个对象,SpiderMonkey 和 SquirrelFish 都以插入顺序给出所有属性;对于数组,它们通常(至少在 SM 中存在特殊情况!)数组索引首先是插入顺序中的所有其他属性。无论对象类型如何,V8、Carakan 和 Chakra 总是先给出数组索引,然后才是所有其他属性。

    【讨论】:

    • 感谢您的信息,但来源是什么?
    猜你喜欢
    • 2022-01-20
    • 2011-10-27
    • 2014-06-29
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    相关资源
    最近更新 更多