Array 函数的 JavaScript 运行时复杂性 [英] JavaScript runtime complexity of Array functions

查看:41
本文介绍了Array 函数的 JavaScript 运行时复杂性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

JS标准对常见的Array函数(如pushpopshift)定义的运行时复杂度,slice 还是 splice?特别是我有兴趣在随机位置删除和插入条目.如果未定义复杂性,我可以期待什么,例如在 V8 中?

Is the runtime complexity defined by the JS standard on common Array functions like push, pop, shift, slice or splice? Esp. I'm interested in removing and inserting entries at random positions. If the complexity is not defined, what can I expect, e.g. in V8?

(这个问题的灵感来自 this.另外,这个基准,发布了这里,也让我好奇,但也许这是一些不相关的现象.)

(This question was inspired by this. Also, this benchmark, posted here, also makes me curious, but maybe that is some unrelated phenomena.)

(一个非常相关的问题是这里.但是,关于接受的答案说它现在是错误的.此外,接受的答案没有任何参考标准真正以这种方式定义它.).

(A very related question is here. However, one of the comments on the accepted answer says that it is wrong now. Also, the accepted answer does not have any reference that the standard really defines it that way.).

推荐答案

ECMA 规范没有指定边界复杂度,但是,您可以从规范的算法中推导出一个边界复杂度.

The ECMA specification does not specify a bounding complexity, however, you can derive one from the specification's algorithms.

pushO(1),但是,在实践中,它会在引擎定义的边界处遇到 O(N) 复制成本为插槽数组需要重新分配.这些边界通常是对数的.

push is O(1), however, in practice it will encounter an O(N) copy costs at engine defined boundaries as the slot array needs to be reallocated. These boundaries are typically logarithmic.

popO(1)push 类似的警告,但 O(N) 复制很少遇到,因为它经常被折叠到垃圾收集中(例如,复制收集器只能复制数组的已使用部分).

pop is O(1) with a similar caveat to push but the O(N) copy is rarely encountered as it is often folded into garbage collection (e.g. a copying collector could only copy the used part of an array).

shift 最差 O(N) 但在特殊情况下,它可以实现为 O(1)减慢索引速度,因此您的里程可能会有所不同.

shift is at worst O(N) however it can, in specially cases, be implemented as O(1) at the cost of slowing down indexing so your mileage may vary.

sliceO(N) 其中 Nend - start.如果没有显着减慢对两个阵列的写入速度,这里的优化机会并不多.

slice is O(N) where N is end - start. Not a tremendous amount of optimization opportunity here without significantly slowing down writes to both arrays.

splice 是,最坏的情况,O(N).有一些数组存储技术将 N 除以一个常数,但它们会显着减慢索引速度.如果引擎使用此类技术,您可能会注意到操作异常缓慢,因为它会在访问模式更改触发的存储技术之间切换.

splice is, worst case, O(N). There are array storage techniques that divide N by a constant but they significantly slow down indexing. If an engine uses such techniques you might notice unusually slow operations as it switches between storage techniques triggered by access pattern changes.

你没有提到的是sort.在平均情况下,O(N log N).但是,根据引擎选择的算法,在某些情况下您可能会得到 O(N^2).例如,如果引擎使用 QuickSort(即使延迟到 InsertionSort),它也有众所周知的 N^2 个案例.这可能是您的应用程序的 DoS 来源.如果这是一个问题,请限制您排序的数组的大小(可能合并子数组)或救助到 HeapSort.

One you didn't mention, is sort. It is, in the average case, O(N log N). However, depending on the algorithm chosen by the engine, you could get O(N^2) in some cases. For example, if the engine uses QuickSort (even with an late out to InsertionSort), it has well-known N^2 cases. This could be a source of DoS for your application. If this is a concern either limit the size of the arrays you sort (maybe merging the sub-arrays) or bail-out to HeapSort.

这篇关于Array 函数的 JavaScript 运行时复杂性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆