c++ - 从保留的 vector 读取比从非保留的 vector 读取更快?

标签 c++ performance

我有以下代码

#include <chrono>
#include <iostream>
#include <vector>

int main() {
struct Point {
 double x, y, z;
};  

const size_t sz = 1'000'000'00;
auto start = std::chrono::steady_clock::now();
std::vector<Point> points;
points.reserve(sz);
for (size_t i = 0; i < sz; ++i) {
  const double d_val = i;
  points.push_back({d_val, 2.0*d_val, 3*d_val});
}
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> diff = end-start;
std::cout << "filling: " << diff.count() << std::endl;
double tot{0};
for (const auto& p : points)
  tot += p.x + p.y + p.z;
diff = std::chrono::steady_clock::now()-end;
std::cout << "reading: " << diff.count() << std::end;
std::cout << tot;
return 0;
}

我得到的结果大约是

filling: 1.78711

reading: 0.233211

但是,如果我删除 points.reserve(sz); 我会得到结果

filling: 8.38341

reading: 1.6607

我明白为什么填充需要更长的时间,但为什么阅读慢得多?

编辑: 1.我使用的是xcode,LLVM 8.0,-O3,

  • 我有一个“cout << tot”(但未将其包含在此处),因此不应将其优化掉。

  • 如果我将所有 cout 延迟到最后(通过节省“填充”变量的时间),我仍然会得到“读取”时间的差异。

  • 最佳答案

    这是一个大胆的猜测,但这可能是因为缓存效应。当您在reserve()之后不断向 vector 添加数据时,某些数据可能会保留在缓存中(回写缓存)。如果您在没有 Reserve() 的情况下继续添加数据,则必须重新定位数据,并且 vector 数据的重新定位可以通过缓存直写复制来完成。您可以通过首先使用一次读取 channel 预热缓存,然后计时第二次读取来测试这一点。

    关于c++ - 从保留的 vector 读取比从非保留的 vector 读取更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39732105/

    相关文章:

    javascript - 在嵌套函数中包含代码(大约 30 行)是更快还是在没有嵌套函数的情况下调用代码更快

    c++ - 什么时候应该在 RapidJSON 中使用 CrtAllocator 和 MemoryPoolAllocator?

    c++ - 当我在 C++ 中删除我的 vector 时,我遇到了双重错误

    c++ - 在 pthread_cond_wait 中取消线程是否会导致它重新获取相关的互斥锁?

    c++ - 尝试加入时线程崩溃

    C++ 字符串到字符串的转换

    php - 距离计算哪个更快 mongodb 或 mysql

    java - Postgresql Replication 解决方案及其性能

    mysql - MySQL中INT和UUID的区别

    c++ - shared_ptr<T> 到 shared_ptr<T const> 和 vector<T> 到 vector<T const>