gpt4 book ai didi

c++重复箭头运算符取消引用性能与点运算符

转载 作者:太空狗 更新时间:2023-10-29 20:37:30 25 4
gpt4 key购买 nike

箭头取消引用 p->m(*p).m 的语法糖,看起来它可能涉及两个独立的内存查找操作——一个查找堆上的对象和第二个对象然后定位成员字段偏移量。

这让我怀疑这两个代码片段之间是否存在任何性能差异。假设 classA 有 30 多个不同类型的不同字段,需要以不同的顺序访问(不一定连续或连续):

版本 1:

void func(classA* ptr)
{
std::string s = ptr->field1;
int i = ptr->field2;
float f = ptr->field3;
// etc...
}

版本 2:

void func(classA* ptr)
{
classA &a = *ptr;
std::string s = a.field1;
int i = a.field2;
float f = a.field3;
// etc...
}

所以我的问题是这两个版本之间是否存在性能差异(即使非常轻微),或者编译器是否足够聪明以使它们等效(即使不同的字段访问被许多行中断它们之间的其他代码,我没有在这里显示)。

最佳答案

Arrow dereferencing p->m is syntactic sugar for (*p).m

这通常不是真的,但在您询问的有限上下文中是真的。

which appears like it might involve two separate memory lookup operations--one to find the object on the heap and the second to then locate the member field offset.

完全没有。一是读取持有指针的参数或局部变量,二是访问成员。但是任何合理的优化器都会将指针保存在您显示的代码中的寄存器中,因此没有额外的访问权限。

但是您的替代版本也有一个本地指针,所以无论如何都没有区别(至少在您询问的方向上):

  classA &a = *ptr;

假设整个函数没有被内联或假设由于某些其他原因编译器不知道 ptr 指向的确切位置,& 必须使用指针,所以要么编译器可以推断出 a*ptr 的别名是安全的,因此没有NO 区别,或者编译器必须使 a *copy_of_ptr 的别名,因此使用 & 的版本由于复制 ptr.

even if the different field accesses are interrupted by many lines of other code in between them, which I did not show here

这会让您转向有趣的案例。如果中间代码可以更改 ptr 那么显然这两个版本的行为不同。但是,如果一个人可以看到中间代码不能更改ptr,而编译器却看不到:那么这两个版本在语义上是相同的,但是编译器不知道这一点,编译器可能会为您尝试通过创建引用手动优化的版本生成较慢的代码。

关于c++重复箭头运算符取消引用性能与点运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34483139/

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