我对JavaScript和数组创建以及实际内存分配做了一些想法,我想听到更多关于这个问题的意见以及我是否正确。
因此,随机时间内电脑中的实际内存可能是这样的:
如果我写:var a = [];
它将在内存的开头创建一个数组。
如果我写a.push(1);
它会删除旧的数组,然后创建一个保留更多内存的新数组,并且在那个时刻可能没有足够的连续内存,因此它必须将块移动到另一个地方。
因此,如果我从一开始就知道数组的长度,使用var a = new Array(5)
比var a = []
更好/更快。
另一方面偏离对象,因为他们没有保留记忆,所以如果我有这些问题,那么这就是:
var object = {};
然后
object.foo = bar;
这将找到下一个可用的内存位置并更新指针。 因此,如果我不知道确切的长度/项目或关心订单,那么使用对象会更好,因为它不会使此删除创建新的数组进程。
答案 0 :(得分:2)
两个评论。
予。可能,阵列的预分配稍微好一些。创建数组时,它占用的内存比元素多(例如,空数组已预先分配了几个插槽),因此在添加元素时,可以立即将其添加到数组中。当没有更多的可用空间被保留时,将重新分配一个数组:从空闲存储器请求更大的连续块,并且到目前为止存储在该数组中的所有元素都被复制到那里。所以,正如你所看到的,重新分配是一个相对昂贵的操作,所以你的猜测是正确的 - 当你事先知道一个数组的大小(或者至少是它的下限,足够大),你宁愿创建一个至少那个确切大小的数组。为了解决这个问题,数组保留大小随着重新分配呈指数级增长,它允许保持平均时间相对较低地添加元素(准确地说是分摊O(1))。
请注意,您应该区分预分配和占用存储。使用Array(5)
创建非空数组时,它已经有五个元素,因此其size
为5.创建空数组时,它没有元素,即其size
是0,但在内部,它包含足够的存储空间,可以立即进行前几次添加。
II。重新分配时,旧存储不是已删除,它只是无法访问(就像所有不再需要的JS对象一样),因此VM知道它是未使用的通过该程序,可以在下一次GC运行期间被标记为空闲。