JavaScript阵列效能

use*_*173 5 javascript arrays firefox google-chrome

我已经找到了关于此的每一个问题和文章,但没有任何答案。我听起来好像只有一个问题,但还有更多问题。

也许我应该先解释一下我要做什么,我完全用JavaScript构建了文件管理器,文件管理器从后端(PHP,Twig)接收文件,然后将它们存储在文件夹数组中,每个文件夹都有自己的文件夹文件,文件夹是一个数组,每个文件夹中的文件也是一个数组,这些文件也显示在页面上,用户可以选择,复制,剪切,粘贴(其他操作)(我仍在编写这些操作) ,因为问题就出在这里)。
页面上的文件分配有数据ID,以便我可以在文件管理器和后端之间轻松地对其进行操作,并且由于我知道每个文件的ID,因此我认为可以完全消除遍历文件数组中的遍历。搜索特定文件,如果我只能创建一个将文件ID作为索引的数组,并且因为这是JavaScript,那么我可以做到!但是有一些问题。

尝试使用Object来完成此任务是行不通的,因为它比Array慢得多(现在,我知道,速度的差异(即使以百万为单位)也没有那么大,但是为什么不尝试挖掘它呢?终极表现,对吗?

因此,这是一个问题列表,我似乎无法找到可靠的答案:

  1. 为什么Chrome上的Object比Firefox上的Object要快得多?
  2. 为什么在Chrome上访问未定义的索引这么慢?
  3. 为什么Array在Firefox上比Chrome快得多?
  4. 我知道为什么Chrome会因为较高的索引而失去性能(在100k时,它将数组转换为列表,我认为这是在SO上的另一个问题中提供了指向源的链接),但是Firefox却逐渐失去了性能,就像它遍历了较高的索引一样顺序地,即使直接访问,那为什么呢?
  5. 当数组中只有一个元素但索引很高时,为什么数组会特别慢?

我可能还有其他问题,但我现在无法想到。


我发现最快的配置支持ID作为索引和索引之间的空缺,并从高索引开始,它使用的是一个Array,该数组保存要存储的数据,另一个数组,仅保存索引,以便当搜索ID为10的对象时,触摸索引Array,而不是带有数据的Array。
您可以在http://jsperf.com/array-management-performance/2中查看此示例。

编辑:如果您想看到性能下降,请“审查”此jsperf并将minId和maxId更改为一些大数字。


以下是一些统计信息:

宾语

读取已定义:Firefox 165173万ops / sec | Chrome 351.699百万次操作/秒
阅读未定义:Firefox 98.582百万次操作/秒| Chrome 5466.60万次/秒
写关闭:Firefox 759.9万次/秒| Chrome浏览器2912.44万次操作/秒
写远:Firefox 559.9万次操作/秒| Chrome 93733万次/秒
写覆盖:Firefox 759.9万次/秒| 镀铬2912.44百万次操作/秒

数组

读取已定义:Firefox 681.206百万次操作/秒| Chrome 401.522百万次操作/秒
阅读未定义:Firefox 681.206百万次操作/秒| Chrome 62.827百万次操作/秒
写入关闭:Firefox 400.234百万次操作/秒| Chrome 121.519百万个操作/秒
Write远:Firefox 348.56百万个操作/秒| Chrome 121.519百万次操作/秒
写入覆盖:Firefox 400.234百万次操作/秒| Chrome 234.337百万次操作/秒

PS:您知道吗,在移动设备上的Chrome浏览器上的“读取已定义”比在桌面设备上的Chrome浏览器更快?

我精打细算我在这里遇到的每个问题,因此我/他人的测试写得不正确,或者这是一些非常时髦的东西。

http://jsperf.com/array-management-performance/2
http://jsperf.com/array-in-the-middle-of-nowhere
http://jsperf.com/object-holey-performance-better
http ://jsperf.com/object-performance-better
http://jsperf.com/array-vs-object-mine-v2/5

PS2我知道,其中一个Array测试实际上是在测试Object,另一个Object测试实际上是在测试Array,请不要指出,我知道,我写了这个,错误是因为jsperf的制作很差,并且我试图相对快速地检查很多不同的设置。

PS3对不起,其中一些测试确实很混乱,我没有想到,我实际上需要向任何人展示它们,但我仍然认为足够。

-------------------------------------------------- -------------------------

编辑:(答案,希望重新打开问题,以便我可以回答)

在这里,我对我们所有的问题都给出了答案。现在,我在阅读答案的同时再次阅读了我的问题,我可以看到我的问题在不深入研究每个浏览器来源的情况下是如何无法轻松地回答或根本无法回答的。

我本人仍然不知道1、2、3、4甚至5的确切答案,但是正确的答案是“由于实现差异”,就这么简单,显然,我没有在这里返回只是这样写,对于这个问题,我有一个解决方案。

简化的问题:您有一组ID,最有可能是从数据库中分配给数据的。您希望将这些数据放在JS数组中,以便可以非常轻松地使用它,但是当将10万个元素放入JS数组时,您不希望失去性能。如何在JS中将N个元素放入数组中而不损失读写性能?(我没有测试写作,因为这对我来说并不那么重要)。

解决方案和说明:在研究此问题时,我检查了许多潜在的解决方案,例如样条曲线,傅立叶变换,哈希表,二进制搜索以及对map / hash表的扭曲,它们实际上表现非常好,但对于我的口味(随着尺寸的增加,它的表现也会变差)。

最终解决方案似乎简单而显而易见,但是以某种方式(我想我很愚蠢)花了我10天的时间弄清楚了,它可以完美地扩展,并且访问任何元素的速度都非常快O(1)。

为了能够编写此解决方案,我使用了JS引擎的以下属性http://jsperf.com/array-of-arrays-with-high-indexes/2,看来对前1000个元素的访问是非常快的(甚至在数组数组中),因为我知道我的数据是无符号整数,所以我可以轻松地将1D到3D的整数映射起来,这样FastArray最多可以容纳10亿个元素。

您可以在这里看到正在运行的解决方案:http : //jsperf.com/map-check-v2/5-第一次测试很慢,因为我从一个简单的数组中读取了示例数据,而且非常慢。 ..编辑:情况似乎并非如此,我真的不知道是什么原因造成的,我认为jsperf有点奇怪,因为运行该测试会产生非常好的结果,非常奇怪。

https://github.com/ImJustAskingDude/JavascriptFastArray在这里是一种更清洁的实现,其中包含对我阅读的每一页的大量引用,以试图弄清楚这一点。

PS4版主。请重新打开此问题,以便搜索Ultimate Array Performance的人们可以在一个很好的实际答案中看到此答案。谢谢。

PS5我不知道为什么,我想我的最终代码中有一个错误,这会使Chrome的性能相对较差,这很容易修复。

Dav*_*mez 0

首先,JS 引擎在每个浏览器上都不同,因此它们在每种情况下的性能并不相同。

另外,你必须记住,JavaScript 中的数组也是对象,唯一的区别是它们以整数作为键值来模拟索引。

当您创建一个只有一个高索引元素的数组时,将创建一个对象,其中所有其他“空间”都填充有undefined值,因此 JS 引擎必须遍历整个结构才能找到您的值。

reduce正如 @RobG 所说,在这种情况下,像、map、 和这样的原生数组方法forEach会表现得更好。

您还可以使用RamdaLodash等函数库来帮助您遍历和展平查询结果。