为什么我们需要使用 folly::fbvector 而不是 std::vector 和最初保留大的未提交区域的分配器?

Why do we need to use folly::fbvector instead of std::vector with allocator which reserve large uncommited area initially?

众所周知,如果我们push_back个元素到std::vector<>,并且如果向量中分配的整个内存都被占用,那么std::vector<>保留当前内存大小的2倍(分配 2 倍大小的新内存),调整向量大小并将旧数据复制到新内存。

我们可以优化它,Facebook 在 folly-library 中做到了这一点(FBVector 是 Facebook drop-in 对 std::vector 的实现。它针对可重定位类型和 jemalloc https://github.com/facebook/folly/blob/master/folly/FBVector.h#L21).

即当 vector<> 没有足够的内存来 push_back 新元素时,我们分配更多的内存但不是 2 倍(不同的次数:1.3 - 1.5 倍)

说明:https://github.com/facebook/folly/blob/master/folly/docs/FBVector.md

The graphical solver below reveals that choosing k = 1.5 (blue line) allows memory reuse after 4 reallocations, choosing k = 1.45 (red line) allows memory reuse after 3 reallocations, and choosing k = 1.3 (black line) allows reuse after only 2 reallocations.

但是为什么我们需要使用 folly::fbvector<> 而不是 std::vector<> 和我们使用 VirtualAllocEx() (as shown here: For what do I need to use VirtualAlloc/VirtualAllocEx? ), or the same in linux 的自定义分配器,其中:

总体:

folly::vector<> 相比,这种具有大 un-commited 区域的方法的优点:我们总是只分配新的内存部分,从不复制旧数据。

folly::vector<> 方法相对于 std::vector<> 的优点:有时我们不需要分配新内存,而是将旧数据复制到新数据中记忆应该永远。

这是特定于实现的。 GCC 库确实分配了两倍的空间,但 Visual C++ 却没有。我相信,它也使用 1.5,但不确定。

我相信,folly 应该与操作系统无关,您的方法是 Windows/Linux-specific。

如果您仔细选择类型,对象从旧向量移动到新向量应该不会那么糟糕 - 也就是说,使用 std::unique_ptr 作为数据类型。