【发布时间】:2017-10-06 22:36:10
【问题描述】:
我一直在尝试在具有一些自定义功能的 JavaScript 中实现类的集合类型(类似于 C# 中的 List)。我还希望对其进行一些优化(我已经阅读了一些关于如何正确使用 JavaScript 数组的文章)。
我对自己说“如果我们没有为数组定义初始大小并且我们不断向其中添加对象,那么在内部它必须为每次插入分配一个新大小,这一定很慢。我可以避免这种情况通过自己分配一个新的大小(更改数组长度),有点类似于在 C# 中的做法,只要达到最大容量,大小就会翻倍(我知道这不是微不足道的,而是一个开始)”。
我尝试实现这个想法,发现它慢了很多(大约慢了 10 倍):
// This simplified approach of my implementation is faster...
var array = [];
var counter = 0;
function addItem(newItem) {
array[++counter] = newItem;
}
// ...then this version that resizes the array when a limit is reached
var array = [];
array.length = INITIAL_SIZE;
/*
Alternatively
var array = new Array(INITIAL_SIZE);
*/
var counter = 0;
function addItem(newItem) {
if( CheckCapacity(counter + 1) ) { // Function that checks if the maximum size is reached and if it is, change the array.length to the new size
array[++counter] = newItem;
}
}
在测试这个之前,我想,“因为当我调用 CheckCapacity(counter + 1) 时数组有了新的大小,所以在内部它 (JavaScript Array) 与第一个函数,因为我确保有可用空间,超过必要”,即第二个函数上的 array[++counter] = newItem 行应该比同一个函数更快第一个函数。
我什至使用了不同的数组,其中包含预先计算的存放物品的大小;还是比较慢。
回到我的问题,JavaScript Array 的实现如何分配必要的大小?我是否正确地假设不能做太多事情来加快这个过程?对我来说,每次添加新项目时动态分配更多内存的对象(JavaScript 数组)的缺点是速度的损失(除非它实现了非常好的算法,但我没有'不知道,因此我的问题)。
【问题讨论】:
-
阵列大小和存储已经在现代用户代理中进行了相当优化。为什么要重新发明轮子?
-
我不确定您是否将
[INITIAL_SIZE]用作更复杂事物的简写,但var array = [INITIAL_SIZE];将创建一个单元素数组,其中第一个元素的值为INITIAL_SIZE。跨度> -
不想重新发明轮子。由于我可以优化许多 Array 方法,如 Splice、Push、Pop 等,我认为我可以对大小管理做一些事情。 JsPerf 上有很多与此相关的测试用例,例如 Array(N) vs [].length vs [] vs {}。我只是想再测试一下。
-
没有“容量”。 JavaScript 数组不存储在连续内存中,因此,它们可以按需增长/缩小,而无需额外开销。更多地将其视为一种链表方法,而不是传统的数组结构。 stackoverflow.com/a/20323491/4987197
-
@mobileDev07
Array(N),[N],[],{}都做了完全不同的事情...
标签: javascript arrays performance