众所周知,如果我们将push_back元素传递给std::vector<>
,并且如果向量中分配的整个内存被占用,则std::vector<>
保留当前大小的内存的2倍(分配2X大小的新内存) ),调整向量并将旧数据复制到新内存。
我们可以优化它,Facebook在愚蠢的库中完成了这个(FBVector是Facebook的std :: vector的实现。它具有特殊的优化,可用于可重定位类型和jemalloc https://github.com/facebook/folly/blob/master/folly/FBVector.h#L21 )。
即。当vector<>
没有足够的内存来推送新元素时,我们会分配更多内存,但不会分配2倍以上(次数不同: 1.3 - 1.5次)
说明:https://github.com/facebook/folly/blob/master/folly/docs/FBVector.md
下面的图形解算器显示选择k = 1.5(蓝线) 允许在4次重新分配后重复使用内存,选择k = 1.45(红色 line)允许在3次重新分配后重复使用内存,并选择k = 1.3 (黑线)允许在仅重新分配2次后重复使用。
但为什么我们需要使用folly::fbvector<>
而不是std::vector<>
使用我的自定义分配器,它使用VirtualAllocEx()
(如下所示:For what do I need to use VirtualAlloc/VirtualAllocEx?),或者在linux中使用相同的https://stackoverflow.com/a/2782910/1558037,其中:
std::vector<>::reserve()
- 最初预留大的未提交虚拟地址区域(分配WMA,但不在PT中分配任何PTE),例如最初分配16 GB的虚拟区域,每次缺少内存提交内存(分配PTE - 分配物理区域)等于1 x SIZE of vector std::vector<>::resize()
- 然后只提交一批新的页面,在PT中只分配新的PTE,而不重新分配已经使用的内存,也不将数据从旧内存复制到新的总体:
这种方法的优势在于folly::vector<>
:上的大量未提交区域,我们始终只分配新内存部分而不会复制旧数据。
folly::vector<>
方法优于std::vector<>
的优势:有时我们不需要分配新内存,但应始终将旧数据复制到新内存中。< / p>
答案 0 :(得分:1)
这是特定于实现的。 GCC库确实分配了两倍,但Visual C ++没有。我相信,它也使用1.5,但不确定。
我相信,folly
应该是与操作系统无关的,你的方法是Windows / Linux特有的。
如果您仔细选择类型,那么从旧向量移动到新向量的对象应该不那么糟糕 - 也就是说,使用std::unique_ptr
作为数据类型。