C++ 向量访问内存的次数几乎是原始指针的两倍-为什么?
关于std::vector的内存行为,我有一个相当基本的问题。我想理解为什么通过向量的简单循环比使用原始指针的相同循环慢得多 这是代码0:C++ 向量访问内存的次数几乎是原始指针的两倍-为什么?,c++,C++,关于std::vector的内存行为,我有一个相当基本的问题。我想理解为什么通过向量的简单循环比使用原始指针的相同循环慢得多 这是代码0: #include<iostream> #include<vector> #include "utils.h" //contains Timer using namespace std; void ff(double * p, int n) { for (int i =0; i< n ; i++) p[i]+=i; }
#include<iostream>
#include<vector>
#include "utils.h" //contains Timer
using namespace std;
void ff(double * p, int n) {
for (int i =0; i< n ; i++) p[i]+=i;
}
int main() {
int n = 1e9;
Timer t; //comes from "utils.h"
t.tic(); //start timer
double * p = new double[n];
ff(p, n);
delete[] p;
double tt = t.toc(); //stop timer
cout << tt << endl; // number of seconds recorded by t.
}
#包括
#包括
#包括“utils.h”//contains Timer
使用名称空间std;
无效ff(双*p,整数n){
对于(inti=0;i CUT 没有优化,所有C++标准库都会比C代码慢。没有优化,所有C都比手写汇编慢。你期望什么?
为了在不进行优化的情况下使用std::vector
,与C中的单个数组写入相比,编译器必须为每次写入向量元素写出大约四个函数调用
至少使用-O2
-O3-DNDEBUG
是我的首选。使用-flto
和-fprofile-generate
/-fprofile-Use
也可以。查找它们
如果你不写C++,那么为什么要使用它呢?
< p>没有优化,所有C++标准库都会比C代码慢。没有优化,所有C都比手写汇编慢。你想什么?
为了在不进行优化的情况下使用std::vector
,与C中的单个数组写入相比,编译器必须为每次写入向量元素写出大约四个函数调用
至少使用-O2
-O3-DNDEBUG
是我的首选。使用-flto
和-fprofile-generate
/-fprofile-Use
也可以。查找它们
如果你不写C++,那么为什么要使用它?< /p>你的代码使用<代码> STD::vector < /Cord>。但是你的文本说:“代码> STD::数组< /Cord>”,也许是看生成的程序集,用于<代码> FF< /C>。你的代码不等价。要使它变为<代码>新的双[n]()实际上,您的第一个代码具有未定义的行为,因为它读取的是未初始化的值。您通过在第一个代码段中读取未初始化的值获得了未定义的行为。向量版本正确地将每个double初始化为0
请注意,我编译了这两个代码,但没有使用优化标志lly使您的比较无效。您的向量实现在调试生成中是否有迭代器和边界检查?您的代码使用std::vector
,但您的文本说的是std::array
-这是什么?也许可以查看生成的程序集以获得ff
。您的代码不等效。若要这样做,请将其更改为new double[n]()实际上,您的第一个代码具有未定义的行为,因为它读取的是未初始化的值。您通过在第一个代码段中读取未初始化的值获得了未定义的行为。向量版本正确地将每个double初始化为0
请注意,我编译了这两个代码,但没有使用优化标志lly使您的比较无效。您的向量实现在调试版本中是否有迭代器和边界检查?将查找并使用它们。谢谢!将查找并使用它们。谢谢!
#include<iostream>
#include<vector>
#include "utils.h"
using namespace std;
void ff(vector<double>& v, int n) {
for (int i =0; i< n ; i++) v[i]+=i;
}
int main() {
int n=1e9;
Timer t;
t.tic();
vector<double> v(n);
ff(v, n);
double tt = t.toc();
cout << tt << endl;
}