Ste*_*phQ 5 c c++ micro-optimization
我想知道(除了明显的语法差异)是否有一个类包含一个对象(相同类型的)的多个实例或该类型的固定大小的对象数组之间的任何效率差异.
在代码中:
struct A {
double x;
double y;
double z;
};
struct B {
double xvec[3];
};
Run Code Online (Sandbox Code Playgroud)
实际上我会使用boost :: arrays,它是C风格数组的更好的C++替代品.
我主要关注构造/破坏和读/写这样的双打,因为这些类通常只是为了调用它们的一个成员函数而构造一次.
感谢您的帮助/建议.
通常,这两个结构的表示将完全相同.但是,如果您为用例选择了错误的性能,则可能性能较差.
例如,如果需要访问循环中的每个元素,可以使用数组:
for (int i = 0; i < 3; i++)
dosomething(xvec[i]);
Run Code Online (Sandbox Code Playgroud)
但是,如果没有数组,您需要复制代码:
dosomething(x);
dosomething(y);
dosomething(z);
Run Code Online (Sandbox Code Playgroud)
这意味着代码重复 - 可以采用任何一种方式.一方面,循环代码更少; 另一方面,在现代处理器上非常紧凑的循环可能非常快,并且代码重复可以吹掉I-cache.
另一个选项是开关:
for (int i = 0; i < 3; i++) {
int *r;
switch(i) {
case 0: r = &x; break;
case 1: r = &y; break;
case 1: r = &z; break;
}
dosomething(*r); // assume this is some big inlined code
}
Run Code Online (Sandbox Code Playgroud)
这避免了可能很大的i-cache占用空间,但会产生巨大的负面性能影响.不要这样做.
另一方面,如果编译器不是很聪明,原则上数组访问可能会更慢:
xvec[0] = xvec[1] + 1;
dosomething(xvec[1]);
Run Code Online (Sandbox Code Playgroud)
由于xvec [0]和xvec [1]是不同的,原则上,编译器应该能够将xvec [1]的值保存在寄存器中,因此它不必在下一行重新加载该值.但是,有些编译器可能不够聪明,不会注意到xvec [0]和xvec [1]没有别名.在这种情况下,使用单独的字段可能会快一点点.
简而言之,并非在所有情况下都是快速的.它是关于将表示与您如何使用它进行匹配.
就个人而言,我建议使用任何使代码在xvec上运行最自然的东西.不值得花费大量的人力时间来担心某些事情,充其量只会产生如此小的性能差异,你只会在微基准测试中发现它.
MVC++ 2010生成了与两个POD结构中读/写完全相同的代码,如您的示例所示.由于读/写的偏移量在编译时是可计算的,因此这并不奇怪.建筑和破坏也是如此.
至于实际表现,一般规则适用:如果重要,如果不重要,请说明 - 为什么要关心?
索引到数组成员对于结构的用户来说可能需要更多的工作,但是再一次,他可以更容易地迭代元素.