在这种情况下,为什么 std::vector 比 new[] 慢?

问题描述 投票:0回答:1

出于性能原因,我想测试

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 在这个例子中表现得这么差吗?

请注意,问题中提供的函数在我的测试版本中略有更改,以防止编译器优化某些函数。然而,它们的改变方式根本不会影响结果。

c++ optimization
1个回答
-3
投票

在 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/

© www.soinside.com 2019 - 2024. All rights reserved.