Javascript 数组性能

标签 javascript arrays google-chrome firefox

关闭。这个问题需要更多focused .它目前不接受答案。












想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .

5年前关闭。




Improve this question




我已经检查了我能找到的每一个关于这个的问题和文章,但没有真正回答它。我听起来好像我只有一个问题,还有更多问题。

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

尝试使用 Object 来完成这项任务是行不通的,因为它比 Array 慢得多(现在,我明白,速度的差异,即使以百万计,也不是那么大,但为什么不尝试挖掘终极性能,对吧?)

所以这里有一个问题列表,我似乎无法找到可靠的答案:

  • 为什么 Chrome 上的 Object 比 Firefox 上的 Object 快得多?
  • 为什么在 Chrome 上访问 undefined index 如此之慢?
  • 为什么 Array 在 Firefox 上比在 Chrome 上快得多?
  • 我知道为什么 Chrome 会因更高的索引而失去性能(在 100k 时,它会将数组转换为列表,我认为,在关于 SO 的另一个问题中通过指向源的链接得到了回答),但是 Firefox 逐渐失去性能,就好像它遍历到更高的索引一样顺序,即使直接访问,为什么?
  • 为什么 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/

    相关文章:

    javascript - 单击其自定义 html 单击时删除联合 js 节点的问题

    javascript - 如何将对象添加到数组中但仅当数组的当前元素为 0 时?

    google-chrome - 在Chrome中为自定义搜索引擎添加建议URL

    jquery - 不同操作系统中相同浏览器中的 CSS 渲染

    javascript - 服务器 API 说它已插入数据库,但事实并非如此

    javascript - SQLite - 由于约束失败而无法执行语句(19 约束失败)

    javascript - JavaScript 练习

    arrays - 是否可以通过包含在另一个数组中来过滤angular.js?

    javascript - 从 ionic 3 中的父对象数组中检索对象数组

    google-chrome - 自定义 Google Chrome *.desktop 文件的问题