gpt4 book ai didi

javascript - 为什么我们可以在 JavaScript 中创建稀疏数组?

转载 作者:行者123 更新时间:2023-12-02 07:29:44 25 4
gpt4 key购买 nike

我想知道像 var foo = new Array(20), var foo = [1,2,3]; 这样的代码的用例是什么foo.length = 10var foo = [,,,] 是(另外,为什么你想使用 delete 运算符而不是仅仅删除数组中的项目)。您可能已经知道,所有这些都会导致稀疏数组。

但是为什么我们可以做上述事情呢?为什么有人想要创建一个默认情况下 length20 的数组(如第一个示例)?为什么有人想要修改和破坏数组的 length 属性(如第二个示例中所示)?为什么有人想做 [, , ,] 之类的事情?为什么要使用delete而不是仅仅从数组中删除元素?有人可以为这些陈述提供一些用例吗?



我花了大约 3 个小时寻找一些答案。没有什么。大多数来源(2ality 博客、JavaScript:权威指南第 6 版,以及当您搜索“JavaScript 稀疏数组”之类的内容时在 Google 搜索结果中弹出的一大堆其他文章)说的唯一一件事是,稀疏数组是奇怪的行为,你应该远离他们。我读到的任何资料都没有解释或至少试图解释为什么我们首先被允许创建稀疏数组。除了 You Don't Know JS: Types & Grammar 之外,这本书讲述了为什么 JavaScript 允许创建稀疏数组:

An array that has no explicit values in its slots, but has a length property that implies the slots exist, is a weird exotic type of data structure in JS with some very strange and confusing behavior. The capability to create such a value comes purely from old, deprecated, historical functionalities ("array-like objects" like the arguments object).

因此,这本书暗示 arguments 对象以某种方式在某处使用我上面列出的示例之一来创建稀疏数组。那么,参数在哪里以及如何使用稀疏数组呢?



另一件让我困惑的事情是《JavaScript:权威指南第六版》一书中的这一部分:

Arrays that are sufficiently sparse are typically implemented in a slower, more memory-efficient way than dense arrays are`.

对我来说,“更高效的内存”似乎与“更慢”是矛盾的,那么两者之间有什么区别,特别是在稀疏数组的情况下? Here是本书特定部分的链接。

最佳答案

I was wondering what the use-cases for code like var foo = new Array(20), var foo = [1,2,3]; foo.length = 10 or var foo = [,,,] were

理论上,出于同样的原因,人们通常使用稀疏数据结构(不一定按重要性顺序排列):内存使用(var x = []; x[0]=123;x[100000]=456; 不会消耗 100000 个“槽”)、性能(例如,取上述 x 的平均值) ,通过 for-in 或 reduce() )和便利(没有“硬”越界错误,不需要显式增长/收缩);

也就是说,从语义上讲,js 数组只是一个特殊的关联集合,具有索引键和特殊属性“length”,满足大于其所有索引属性的不变量。虽然是一个非常优雅的定义,但正如您所注意到的,它的缺点是渲染稀疏定义的数组有些困惑且容易出错。

But why are we allowed to do the above thnigs ?

即使我们不允许定义稀疏数组,我们仍然可以将未定义的元素放入数组中,从而导致与稀疏数组基本相同的可用性问题。因此,假设 [0,undefined,...,undefined,1,undefined][0,...,1,] 相同,只会带来更多内存消耗数组和更慢的迭代。

Arrays that are sufficiently sparse are typically implemented in a slower, more memory-efficient way than dense arrays are. more memory-efficient and slower appear like a contradiction to me

用于通用数据的“密集数组”通常被实现为填充有相同大小元素的连续内存块;如果添加更多元素,则继续填充内存块,如果耗尽则分配新 block 。鉴于重新分配意味着将所有元素移动到新的内存块,通常会大量分配所述内存,以最大限度地减少重新分配的机会(类似于黄金比例乘以最后的容量)。因此,这样的数据结构通常对于有序/本地遍历来说是最快的(对 CPU/缓存更友好),对于不可预测的插入/删除来说是最慢的(对于足够大的 N ),并且具有很高的内存开销 ~ sizeof(elem) * N + extra future 元素的空间。

相反,“稀疏数组/矩阵/...”是通过将分布在内存中的较小内存块“链接”在一起或使用密集数据结构的某种“逻辑压缩”形式或两者来实现的;在任何一种情况下,由于显而易见的原因,内存消耗都会减少,但相对而言,遍历它们需要更多的工作和更少的本地内存访问模式。

因此,如果与相同的有效遍历元素相比,稀疏数组消耗的内存要少得多,但速度比密集数组慢得多。然而,考虑到您使用带有稀疏数据的稀疏数组和对“零”起作用的算法,稀疏数组在某些情况下可以变得更快(例如,将非常大的矩阵与很少的非零元素相乘......)。

关于javascript - 为什么我们可以在 JavaScript 中创建稀疏数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46526520/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com