gpt4 book ai didi

c++ - vector 与数组性能

转载 作者:可可西里 更新时间:2023-11-01 17:26:02 27 4
gpt4 key购买 nike

在另一个线程中,我开始了关于 vector 和数组的讨论,其中我主要是在唱反调,以插入按钮。然而,在这个过程中,我偶然发现了一个让我有点困惑的测试用例,我想就它进行真正的讨论,关于我因为唱反调而受到的“虐待”,开始一个真正的现在不可能对该线程进行讨论。但是,具体的例子让我很感兴趣,我无法对自己进行令人满意的解释。

讨论的是 vector 与数组的一般性能,忽略了动态元素。例如:显然在 vector 中连续使用 push_back() 会减慢它的速度。我们假设 vector 和数组预先填充了数据。我提出的示例,随后由线程中的个人修改,如下所示:

#include <iostream>
#include <vector>
#include <type_traits>
using namespace std;

const int ARRAY_SIZE = 500000000;

// http://stackoverflow.com/a/15975738/500104
template <class T>
class no_init_allocator
{
public:
typedef T value_type;

no_init_allocator() noexcept {}
template <class U>
no_init_allocator(const no_init_allocator<U>&) noexcept {}
T* allocate(std::size_t n)
{return static_cast<T*>(::operator new(n * sizeof(T)));}
void deallocate(T* p, std::size_t) noexcept
{::operator delete(static_cast<void*>(p));}
template <class U>
void construct(U*) noexcept
{
// libstdc++ doesn't know 'is_trivially_default_constructible', still has the old names
static_assert(is_trivially_default_constructible<U>::value,
"This allocator can only be used with trivally default constructible types");
}
template <class U, class A0, class... Args>
void construct(U* up, A0&& a0, Args&&... args) noexcept
{
::new(up) U(std::forward<A0>(a0), std::forward<Args>(args)...);
}
};

int main() {
srand(5); //I use the same seed, we just need the random distribution.
vector<char, no_init_allocator<char>> charArray(ARRAY_SIZE);
//char* charArray = new char[ARRAY_SIZE];
for(int i = 0; i < ARRAY_SIZE; i++) {
charArray[i] = (char)((i%26) + 48) ;
}

for(int i = 0; i < ARRAY_SIZE; i++) {
charArray[i] = charArray[rand() % ARRAY_SIZE];
}
}

当我在我的机器上运行它时,我得到以下终端输出。第一次运行时 vector 行未注释,第二次运行时数组行未注释。我使用了最高级别的优化,为 vector 提供了最大的成功机会。下面是我的结果,前两次运行时数组行未注释,后两次运行 vector 行。

//Array run # 1
clang++ -std=c++11 -stdlib=libc++ -o3 some.cpp -o b.out && time ./b.out

real 0m20.287s
user 0m20.068s
sys 0m0.175s

//Array run # 2
clang++ -std=c++11 -stdlib=libc++ -o3 some.cpp -o b.out && time ./b.out

real 0m21.504s
user 0m21.267s
sys 0m0.192s

//Vector run # 1
clang++ -std=c++11 -stdlib=libc++ -o3 some.cpp -o b.out && time ./b.out

real 0m28.513s
user 0m28.292s
sys 0m0.178s

//Vector run # 2
clang++ -std=c++11 -stdlib=libc++ -o3 some.cpp -o b.out && time ./b.out

real 0m28.607s
user 0m28.391s
sys 0m0.178s

数组优于 vector 并不让我感到惊讶,然而,差异大约 50% 令我非常惊讶,我希望它们可以忽略不计,而且我觉得这个测试用例的性质是模糊了结果的性质。当您在较小的数组大小上运行此测试时,性能差异会急剧消失。

我的解释:

vector 的额外实现指令导致 vector 指令在内存中对齐不佳,甚至在这个例子中,在 2 个不同的“ block ”上的一个非常糟糕的点上 split 。这导致内存在缓存级别、数据缓存级别和指令缓存级别之间来回跳转的频率比您预期的要高。我还怀疑 LLVM 编译器可能夸大了弱点,并且由于一些较新的 C++11 元素而优化不佳,尽管除了假设和猜想之外,我没有任何理由支持这些解释。

我感兴趣的是 A:有人可以复制我的结果,B:如果有人对计算机如何运行这个特定的基准测试有更好的解释,以及为什么 vector 在这种情况下表现如此明显地低于数组。

我的设置:http://www.newegg.com/Product/Product.aspx?Item=N82E16834100226

最佳答案

一个更简单的解释:您在构建时禁用了优化。您需要 -O3,而不是 -o3

我没有可用的 clang 来准确重现您的测试,但我的结果如下:

//Array run # 1
$ g++ -std=c++11 -O3 test.cpp -o b.out && time ./b.out

real 0m25.323s
user 0m25.162s
sys 0m0.148s

//Vector run #1
$ g++ -std=c++11 -O3 test.cpp -o b.out && time ./b.out

real 0m25.634s
user 0m25.486s
sys 0m0.136s

关于c++ - vector 与数组性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16446684/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com