关闭。这个问题需要更多focused .它目前不接受答案。
想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .
5年前关闭。
Improve this question
我已经检查了我能找到的每一个关于这个的问题和文章,但没有真正回答它。我听起来好像我只有一个问题,还有更多问题。
也许我应该首先解释我想要做什么,我正在完全用 JavaScript 构建一个文件管理器,文件管理器从后端(PHP、Twig)接收文件,然后将它们存储在一个文件夹数组中,每个文件夹都有自己的Files, Folders 是一个数组,每个文件夹中的 Files 也是一个数组,这些文件也显示在页面上,用户可以选择、复制、剪切、粘贴(其他操作)它们(我还在写这些操作,因为问题就在这里)。页面上的文件都分配了数据 ID,这样我就可以轻松地在文件管理器和后端之间对它们进行操作,并且因为我知道每个文件的 ID,我想我可以完全消除遍历文件数组搜索特定文件,如果我只能创建一个将文件 ID 作为索引的数组,并且因为这是 JavaScript,我可以做到!但它存在一些问题。
尝试使用 Object 来完成这项任务是行不通的,因为它比 Array 慢得多(现在,我明白,速度的差异,即使以百万计,也不是那么大,但为什么不尝试挖掘终极性能,对吧?)
所以这里有一个问题列表,我似乎无法找到可靠的答案:
我可能还有一些问题,但我现在想不起来。
我发现的最快的配置,支持 ID 作为索引和它们之间的孔,以及从高索引开始,是使用一个数组来保存你想要存储的数据,另一个数组只保存索引,这样当您搜索 ID 为 10 的对象时,您触摸索引数组,而不是带有数据的数组。
您可以在 http://jsperf.com/array-management-performance/2 中看到这样的示例。 .
编辑:
如果你想看到性能下降,请“审查”这个 jsperf 并将 minId 和 maxId 更改为一些大数字。
以下是一些统计数据:
目的
读取定义:Firefox 16517.3 万次操作/秒 | Chrome 35169.9 万次操作/秒
读取未定义:Firefox 9858.2 万次操作/秒 | Chrome 5466.6 万次操作/秒
写入关闭:Firefox 759.9 万次操作/秒 | Chrome 29124.4 万次操作/秒
远写:Firefox 559.9 万次操作/秒 | Chrome 9373.3 万次操作/秒
写覆盖:Firefox 759.9 万次操作/秒 | Chrome 29124.4 万次操作/秒
大批
读取定义:Firefox 681.206 百万次操作/秒 | Chrome 40152.2 万次操作/秒
读取未定义:Firefox 681.206 百万次操作/秒 | Chrome 6282.7 万次操作/秒
写入关闭:Firefox 40023.4 万次操作/秒 | Chrome 12151.9 万次操作/秒
远写:Firefox 34856.0 万次操作/秒 | Chrome 12151.9 万次操作/秒
写覆盖:Firefox 40023.4 万次操作/秒 | Chrome 23433.7 万次操作/秒
附言您知道吗,在移动版 Chrome 上读取定义比在桌面版 Chrome 上更快?
我对这里遇到的每一个问题都进行了 jsperf-ed,所以要么我/其他人的测试写错了,要么这是一些非常时髦的东西。
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 制作得很差,我试图相对快速地检查很多不同的设置。
P.S.3 抱歉,有些测试真的很乱,我没想到,我实际上需要向任何人展示它们,但我仍然认为已经足够了。
-------------------------------------------------- -------------------------
编辑:(回答,希望重新打开问题,以便我可以回答)
在这里,我将回答我们所有(我的)问题。现在我再次阅读了我的问题,在得到答案的同时,我可以看到我的问题如何无法轻松回答,或者根本无法回答,而无需深入研究每个浏览器的来源。
1、2、3、4甚至5的确切答案我自己仍然不知道,但正确的答案是“因为实现差异”,就这么简单,显然,我没有回到这里就这样写,我有一个解决我在这个问题中展示的问题的方法。
简化问题:
您有一组 ID,这些 ID 分配给数据,很可能来自数据库。
您希望在 JS 中的数组中使用该数据,以便您可以非常轻松地使用它,但您不想在将 100k 个元素放入 JS 数组时损失性能。如何在不损失读/写性能的情况下将 N 个元素放入 JS 中的数组中? (我没有试写,因为它对我来说并不重要)。
解决方法及说明:
在研究这个问题时,我检查了许多潜在的解决方案,比如样条曲线、傅立叶变换、哈希表、二分搜索和映射/哈希表的扭曲,它们实际上表现得很好,但对我的口味来说还不够(它随着尺寸的增加,性能也会变差)。
最终的解决方案似乎非常简单明了,但不知何故(我想我很笨)我花了 10 天的时间才弄明白,它完美地扩展,并且对任何元素的访问都非常快 O(1)。
为了能够编写这个解决方案,我使用了 JS 引擎的这个属性 http://jsperf.com/array-of-arrays-with-high-indexes/2 ,看起来,对前 1000 个元素的访问速度非常快(即使在数组数组中),而且因为我知道我的数据是无符号整数,所以我可以轻松地将整数从 1D 映射到 3D,这样 FastArray 可以容纳a 十亿个元素。
您可以在此处查看此解决方案的实际效果:http://jsperf.com/map-check-v2/5 -- 第一个测试很慢,因为我从一个简单的数组中读取样本数据,而且速度很慢... 编辑:这似乎不是这种情况,我真的不知道是什么原因造成的,我想jsperf 有点吓人,因为只运行该测试会产生非常好的结果,非常奇怪。
更干净的实现在这里 https://github.com/ImJustAskingDude/JavascriptFastArray对我阅读的每一页都有很多引用,试图弄清楚这一点。
P.S.4 版主。请重新打开这个问题,以便搜索 Ultimate Array Performance 的人可以在一个不错的实际答案中看到这个答案。
谢谢。
P.S.5 我不知道为什么,我猜我的最终代码中有一个错误,导致 Chrome 性能相对较差,这可能很容易修复。
最佳答案
首先,JS 引擎在每个浏览器上都不同,因此它们在每种情况下的表现并不相同。
此外,您必须记住 JavaScript 中的数组也是对象,唯一的区别是它们以整数作为键值来模拟索引。
当你创建一个只有一个元素处于高索引的数组时,对象将被创建,所有其他“空间”都填充了 undefined
值,因此 JS 引擎必须遍历整个结构才能找到您的值。
正如@RobG 所说,原生数组方法如 reduce
, map
, 和 forEach
在这种情况下会表现得更好。
你也可以使用像 Ramda 这样的函数库或 Lodash帮助您遍历和展平查询结果。
关于Javascript 数组性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32899054/