dou*_*Ort 6 javascript sparse-matrix
var foo = new Array(20)我想知道、var foo = [1,2,3]; foo.length = 10或 等代码的用例是什么var foo = [,,,](另外,为什么要使用delete运算符而不是仅从数组中删除项目)。您可能已经知道,所有这些都会导致稀疏数组。
但为什么我们被允许做上述事情呢?为什么有人想要创建一个默认为 的数组length(20如第一个示例中所示)?为什么有人想要修改和破坏length数组的属性(如第二个示例)?为什么有人想做类似的事情[, , ,]?为什么要使用delete而不是仅仅从数组中删除元素?有人可以为这些陈述提供一些用例吗?
一个数组在它的槽中没有明确的值,但是有一个 length 属性来暗示槽的存在,这是 JS 中一种奇怪的奇异数据结构类型,具有一些非常奇怪和令人困惑的行为。创建这样一个值的能力纯粹来自旧的、已弃用的历史功能(“类似数组的对象”,如参数对象)。
因此,这本书暗示该arguments对象以某种方式在某处使用我上面列出的示例之一来创建稀疏数组。那么,在哪里以及如何arguments使用稀疏数组呢?
足够稀疏的数组通常以比密集数组更慢、更节省内存的方式实现。
对我来说,“内存效率更高”似乎与“速度较慢”相矛盾,那么两者之间有什么区别,尤其是在稀疏数组的情况下?这是本书特定部分的链接。
我想知道像 var foo = new Array(20), var foo = [1,2,3]; 这样的代码的用例是什么 foo.length = 10 或 var foo = [,,,] 是
理论上,出于同样的原因,人们通常使用稀疏数据结构(不一定按重要性顺序):内存使用量(var x = []; x[0]=123;x[100000]=456;不会消耗 100000 个“槽”)、性能(例如,取上述 x 的平均值,通过 for- in 或 reduce() )和便利性(没有“硬”越界错误,不需要显式增长/收缩);
也就是说,从语义上讲,js 数组只是一个特殊的关联集合,具有索引键和特殊属性“length”,满足大于其所有索引属性的不变量。虽然这是一个非常优雅的定义,但正如您所注意到的,它的缺点是渲染稀疏定义的数组有些混乱且容易出错。
但为什么我们被允许做上述事情呢?
即使我们不允许定义稀疏数组,我们仍然可以将未定义的元素放入数组中,从而导致与稀疏数组基本相同的可用性问题。所以,说,拥有[0,undefined,...,undefined,1,undefined]与 相同的东西[0,...,1,]只会给你带来更多的内存消耗数组和更慢的迭代。
足够稀疏的数组通常比密集数组以更慢、更节省内存的方式实现。对我来说,内存效率更高和速度更慢似乎是矛盾的
用于通用数据的“密集数组”通常被实现为充满相同大小元素的连续内存块;如果添加更多元素,则继续填充内存块,如果耗尽则分配新块。鉴于重新分配意味着将所有元素移动到新的内存块,通常会大量分配所述内存,以最大限度地减少重新分配的机会(类似于黄金比例乘以最后的容量)。因此,这样的数据结构通常对于有序/本地遍历来说是最快的(对 CPU/缓存更友好),对于不可预测的插入/删除来说是最慢的(对于足够大的 N ),并且具有很高的内存开销 ~ sizeof(elem) * N + extra未来元素的空间。
相反,“稀疏数组/矩阵/...”是通过将分布在内存中的较小内存块“链接”在一起或使用密集数据结构的某种“逻辑压缩”形式或两者来实现的;在任何一种情况下,由于明显的原因,内存消耗都会减少,但遍历它们相对需要更多的工作和更少的本地内存访问模式。
因此,如果与相同的有效遍历元素相比,稀疏数组消耗的内存要少得多,但比密集数组慢得多。然而,考虑到您使用带有稀疏数据的稀疏数组和对“零”起作用的算法,稀疏数组在某些情况下可以变得更快(例如,将非常大的矩阵与很少的非零元素相乘......)。
| 归档时间: |
|
| 查看次数: |
1482 次 |
| 最近记录: |