我读过这篇文章:
https://gamealchemist.wordpress.com/2013/05/01/lets-get-those-javascript-arrays-to-work-fast/
在第6点结束时,作者说:
关于shift / unshift的Rq:注意,那些总是O(n)操作 (意思是:每个操作都需要一个与数字成比例的时间 数组长度)。除非你真的需要,否则你不应该使用 他们。如果您需要这样的功能,请构建您自己的旋转阵列。
在第7点:
Shift / unshift用户的Rq:应用相同的原则,有两个 索引,以避免复制/重新分配。左边有一个索引,一个在左边 对,都从阵列的中间开始。然后你会再次 在O(1)时间。更好。不要忘记将索引重新置于中心位置 是==。
我想知道作者在说build your own rotating array
和two indexes,...One index on the left, one on the right, both starting at the middle of the array
时的意思。如何将这些考虑因素转化为代码(作者没有为这个用例做出示例)?
适用于shift
和unshift
的原则是否也适用于Array.prototype.splice
?
编辑:我有一个x
坐标的有序数组,从索引0
(x
的较低值)到n
(更高) x
值)。我需要多次使用myArray.splice(index, 0, item);
并在已存在的坐标之间插入一些新的x
坐标,如果此坐标为较高的<
而较低的>
(我可以很容易地通过二进制搜索找到它)并且我不希望它每次调用splice
时重新排序索引因为我在数组myArray
中有数千个元素。
是否可以使用链接文章作者提到的原则进行改进?
感谢您的关注。
答案 0 :(得分:1)
所有性能问题都必须通过编写一个非常具体的解决方案来解决,然后在您关注的浏览器中使用代表性数据测量该解决方案的性能。很少有性能问题能够通过抽象问题准确回答,而问题不包括要测量的精确代码。
有一些常识性项目,比如你是否要在一个数组中放入1000个项目,那么是的,将数组预先分配到最终长度可能更快,然后只需填写数组值而不是调用.push()
1000次。但是,如果你想知道它有多大差异以及它在你的特定情况下是否真正相关,那么你需要编写两个比较代码并在http://jsperf.com之类的工具中在多个浏览器中测量它们。
该文章中关于创建自己的.splice()
函数的建议似乎在没有测量的情况下对我怀疑。好像.splice()
的良好本机代码实现可能比完全用Javascript编写的实现更快。同样,如果你真的想知道,你将不得不测量一个特定的测试用例。
如果要进行大量的数组操作,并希望最终得到一个排序数组,那么删除项目,将新项目添加到数组末尾以及调用.sort()
时可能会更快您正在执行的自定义比较功能,而不是按排序顺序插入每个新项目。但是,哪种方式更快将完全取决于您正在做什么,您经常做什么以及您最关心的浏览器。衡量,衡量,衡量您是否真的想知道。
至于您是否可以使用自定义.splice()
改进编辑中的具体情况,您必须使用代表性数据集对其进行双向编码,然后在像perf这样的工具中进行测试多个浏览器来回答这个问题。由于您还没有提供测试代码或数据,因此我们都无法真正为您解答。对于所有可能的浏览器中所有可能的数据集,.splice()
的所有可能用途都没有通用的答案。魔鬼在细节中,细节与你的具体情况有关。
我的猜测是,如果你真的在进行性能调整,你会经常发现更大的鱼来使你的整体算法变得更聪明(因此它首先要做的工作要少),而不是尝试重写数组方法。我们的目标是进行足够的测试/测量,以了解您的性能瓶颈究竟在哪里,这样您就可以专注于一个最大差异的领域而不是花费大量时间来猜测什么可能使事情变得更快。我总是会对现有阵列方法的智能使用进行编码,并且只有当我向自己证明我在某个特定操作中存在瓶颈时才考虑自定义编码解决方案,这对我的体验非常重要应用程序。每次优化只会使代码更复杂,维护更少,并且通常会耗费时间。
答案 1 :(得分:0)
我当时在想同样的问题,最终使用B + tree数据结构。这需要时间,并且不容易实现,但效果确实很好。可以考虑将数组和链表的优点结合起来:
我想听听您的想法,您可以查看此链接以了解实际的visualization of b+tree。