出于性能原因,我想测试
std::vector
和 new[]
之间的速度差异。在这样做的过程中,我得到了意想不到的结果。
为了获得结果,我使用了以下两个函数:
void test_copy_vectors(int size) {
std::vector<int> int_vector(size);
std::vector<int> copy_vector(size);
std::copy_n(int_vector.begin(), size, copy_vector.begin());
}
对于
new[]
我用过
void test_copy_new(int size) {
int *elements = new int[size]();
int *elements_copy = new int[size]();
std::memcpy(elements_copy, elements, size * sizeof(int));
delete[] elements;
delete[] elements_copy;
}
然后为了获得我的结果,我在
main()
中使用了它们,如下所示:
int main(int argc, char **argv) {
(void) argc;
int size = std::stoi(std::string(argv[1]));
auto start = std::chrono::high_resolution_clock::now();
test_copy_vectors(size);
auto stop = std::chrono::high_resolution_clock::now();
std::cout << "Vector example took: " <<
std::chrono::duration_cast<std::chrono::milliseconds>(stop - start).count()
<< " milliseconds" << std::endl;
start = std::chrono::high_resolution_clock::now();
test_copy_new(size);
stop = std::chrono::high_resolution_clock::now();
std::cout << "new[] example took: " <<
std::chrono::duration_cast<std::chrono::milliseconds>(stop - start).count()
<< " milliseconds" << std::endl;
return 0;
}
最后,我用
clang++ main.cpp -O3 -o main
编译了程序,并运行了以下测试用例:./main 100000000
。
这是我的结果:
std::vector | new[]
----------------------------
Time: 343ms | 46ms
274ms | 48ms
212ms | 48ms
238ms | 47ms
平均
new[]
比 std::vector 快大约 5.68 倍,但是考虑到我在网上找到的资源都表明 std::vector
不应该产生任何剧烈的速度,我预计它们的速度或多或少相同单个内存分配的性能损失。
考虑到这种情况,有什么理由可以解释为什么 std::vector 在这个例子中表现得这么差吗?
请注意,问题中提供的函数在我的测试版本中略有更改,以防止编译器优化某些函数。然而,它们的改变方式根本不会影响结果。
在 std::vector 和 new[] 之间的比较中,您观察到的性能差异可归因于以下几个因素:
动态内存分配开销:std::vector 内部管理动态内存分配,与 new[] 执行的单个分配相比,这涉及额外的开销。每个 std::vector 对象可能涉及单独的分配和释放调用,而不是 new[] 中的单个分配和释放调用。
初始化开销:在 test_copy_vectors 函数中,您使用默认初始化值初始化 std::vector,而在 test_copy_new 中,您使用 std::memcpy 直接复制内存。与 new[] 中的直接内存复制相比,std::vector 中的初始化过程可能会增加开销。
内存碎片:使用 new[],您分配一个连续的内存块,与 std::vector 管理的内存相比,这在内存布局和缓存利用率方面可能更有效,后者可能涉及更小的、非由于其动态调整大小行为,连续的内存块。
优化:虽然 std::vector 和 new[] 都可以由编译器优化,但优化潜力可能不同。在这种特定情况下,std::vector 的编译器优化可能不那么有效,导致与使用 new[] 手动管理内存相比性能较差。
为了减轻性能差异,您可以考虑:
如果您事先知道大小,请使用 Reserve() 在 std::vector 中预分配空间,以避免重复重新分配。 在适用的情况下使用移动语义来最大限度地减少 std::vector 中不必要的复制开销。 使用不同的优化标志进行分析和试验,看看是否可以缩小 std::vector 和 new[] 之间的性能差距。 总之,虽然 std::vector 通常为了方便和安全而进行了优化,但在某些情况下,使用 new[] 进行手动内存管理可以提供更好的性能,特别是当微调内存使用和最小化开销至关重要时。 欲了解更多信息,请访问https://recipedoor.com/