我有一个现有的算法,如果可能的话,我需要稍微优化它。目前不考虑在该算法中进行大量更改。该算法使用 std::vector< std::vector<unsigned char> >
实例。它看起来像这样:
typedef std::vector<unsigned char> internal_vector_t;
std::vector< internal_vector_t > internal_vectors;
while (fetching lots of records) {
internal_vector_t tmp;
// reads 1Mb of chars in tmp...
internal_vectors.push_back(tmp);
// some more work
}
// use this internal_vectors
算法使用push_back()在internal_vectors中插入很多次internal_vector_t实例。大部分的internal_vector_t实例大小为1 Mb。由于internal_vectors的大小未知,因此没有提前进行reserve()。
我不明白的第一件事是当internal_vectors达到其当前容量时会发生什么,需要分配一个新块并将其当前内容复制到更大的内存块中。由于大多数块的大小为1Mb,复制是一个漫长的操作。我是否应该期望编译器(gcc 4.3、MS VC++ 2008)能够优化它以避免复制?
如果无法避免复制,改用std::deque是否有帮助?我考虑std::deque,因为我仍然需要通过索引访问,比如internal_vectors[10]。
typedef std::vector<unsigned char> internal_vector_t;
std::deque< internal_vector_t > internal_vectors;
// the same while
据我所了解,
std::deque
不需要重新分配已经分配的内存。在这种情况下,std::deque
在 push_back 操作时需要较少的分配和复制。更新: 1)根据 DeadMG MSVC9 进行了这种类型的优化(Swaptimization - TR1 Fixes In VC9 SP1)。gcc 4.3 可能不会进行这种类型的优化。
2)我已经对使用
std::deque< std::vector<unsigned char> >
的算法版本进行了性能分析,发现其性能更好。3)我还使用了 Mark Ransom 建议的使用
swap
。使用后,性能得到了改善。 internal_vector_t tmp;
internal_vectors.push_back(empty);
tmp.swap(internal_vectors.back());
insert
还是push_back
?代码中写的是insert
,但是实际上应该是push_back
,因为对于 vector 来说,它们的成本是非常不同的。 - David Rodríguez - dribeaspush_back
,并在我的问题中修正了它。 - user184968