gpt4 book ai didi

c++ - 为什么访问类的私有(private)变量与访问结构的变量一样高效?

转载 作者:可可西里 更新时间:2023-11-01 16:34:19 24 4
gpt4 key购买 nike

我实现了一些主要数据结构是树的算法。我用一个类来表示一个节点,用一个类来表示一棵树。因为节点经常更新,所以我调用了很多 setter 和 getter。

因为我多次听说函数调用很昂贵,所以我在想,也许如果我用结构体来表示节点和树,它会使我的算法在实践中更有效率。

在这样做之前,我决定进行一个小实验,看看是否确实如此。

我创建了一个类,它有一个私有(private)变量、一个 setter 和一个 getter。我还创建了一个也有一个变量的结构,没有 setter/getter,因为我们可以通过调用 struct.varName 来更新变量。以下是结果:

enter image description here

运行次数就是我们调用setter/getter的次数。下面是实验代码:

#include <iostream>
#include <fstream>

#define BILLION 1000000000LL

using namespace std;

class foo{
private:
int a;
public:

void set(int newA){
a = newA;
}
int get(){
return a;
}
};

struct bar{
int a;
};

timespec startT, endT;

void startTimer(){
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &startT);
}

double endTimer(){
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &endT);
return endT.tv_sec * BILLION + endT.tv_nsec - (startT.tv_sec * BILLION + startT.tv_nsec);
}


int main() {

int runs = 10000000;
int startRun = 10000;
int step = 10000;
int iterations = 10;
int res = 0;
foo f;
ofstream fout;
fout.open("stats.txt", ios_base::out);
fout<<"alg\truns\ttime"<<endl;
cout<<"First experiment progress: "<<endl;
int cnt = 0;
for(int run = startRun; run <= runs; run += step){
double curTime = 0.0;
for(int iter = 0; iter < iterations; iter++) {
startTimer();
for (int i = 1; i <= run; i++) {
f.set(i);
res += f.get();
}
curTime += endTimer()/iterations;
cnt++;
if(cnt%10 == 0)
cout<<cnt/(((double)runs-startRun+1)/step*iterations)*100<<"%\r";
}
fout<<"class\t"<<run<<"\t"<<curTime/BILLION<<endl;
}

int res2 = 0;
bar b;
cout<<"Second experiment progress: "<<endl;
cnt = 0;
for(int run = startRun; run <= runs; run += step){
double curTime = 0.0;
for(int iter = 0; iter < iterations; iter++) {
startTimer();
for (int i = 1; i <= run; i++) {
b.a = i;
res2 += b.a;
}
curTime += endTimer()/iterations;
cnt++;
if(cnt%10 == 0)
cout<<cnt/(((double)runs-startRun+1)/step*iterations)*100<<"%\r";
}
fout<<"struct\t"<<run<<"\t"<<curTime/BILLION<<endl;
}

fout.close();
cout<<res<<endl;
cout<<res2<<endl;

return 0;
}

我不明白为什么会出现这种行为。我认为函数调用更昂贵?

编辑:我在没有 -O3 的情况下重新运行相同的实验

enter image description here

编辑:好的,这是非常令人惊讶的,通过在名为 foo.h 的单独文件中声明类,在 foo.cpp 中实现 getters/setters 并运行-O3,看来类(class)变得更加低效了。

enter image description here

最佳答案

I have heard many times that function calls are expensive.

这是在 1970 年吗?

编译器很聪明。很聪明。他们会根据您的源代码生成最好的程序,除非您正在做一些非常奇怪的事情,否则这些设计更改不太可能产生太大(如果有的话)性能差异。

这里最值得注意的是,在大多数情况下,一个简单的 getter/setter 甚至可以完全内联(除非您正在做一些奇怪的事情),使您的两个程序在编译后有效地相同!您可以在图表上看到此结果。

同时,将 class 替换为 struct 的具体更改对性能没有任何影响 - 两个关键字都定义了一个 class

I don't understand why I get this behaviour. I thought that function calls were more expensive?

看,这就是我们不过早优化的原因。编写清晰、易于阅读的代码,无需技巧,让您的编译器处理其余部分。这是它的工作,而且它通常非常擅长。

关于c++ - 为什么访问类的私有(private)变量与访问结构的变量一样高效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36915277/

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