箭头解引用p->m是 for 的语法糖(*p).m,它看起来可能涉及两个单独的内存查找操作——一个是在堆上找到对象,第二个是然后定位成员字段偏移量。
这让我怀疑这两个代码片段之间是否存在性能差异。假设classA有 30 多个不同类型的不同字段需要以各种顺序访问(不一定连续或连续):
版本 1:
void func(classA* ptr)
{
std::string s = ptr->field1;
int i = ptr->field2;
float f = ptr->field3;
// etc...
}
Run Code Online (Sandbox Code Playgroud)
版本 2:
void func(classA* ptr)
{
classA &a = *ptr;
std::string s = a.field1;
int i = a.field2;
float f = a.field3;
// etc...
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是这两个版本之间的性能是否存在差异(即使非常微小),或者编译器是否足够聪明使它们等效(即使不同的字段访问被许多其他代码行中断)在它们之间,我没有在这里展示)。
箭头取消引用 p->m 是 (*p).m 的语法糖
这通常不是真的,但在您询问的有限上下文中确实如此。
看起来它可能涉及两个单独的内存查找操作——一个是在堆上找到对象,第二个是然后定位成员字段偏移量。
一点也不。一个是读取持有指针的参数或局部变量,第二个是访问成员。但是任何合理的优化器都会将指针保存在您显示的代码中的寄存器中,因此没有额外的访问权限。
但是您的替代版本也有一个本地指针,所以无论如何都没有区别(至少在您询问的方向上):
classA &a = *ptr;
Run Code Online (Sandbox Code Playgroud)
假设整个函数没有被内联或假设由于某些其他原因编译器不知道确切ptr指向哪里,则&必须使用指针,因此编译器可以推断出它是安全a的别名,*ptr因此没有区别,或者编译器必须创建a一个别名,*copy_of_ptr因此使用 a 的版本&由于复制ptr.
即使不同的字段访问被它们之间的许多其他代码行中断,我没有在这里展示
这会让你走向有趣的案例。如果中间代码可以更改,ptr那么显然这两个版本的行为会有所不同。但是,如果人类可以看到中间代码无法更改ptr而编译器无法看到,那该怎么办:那么这两个版本在语义上是相等的,但编译器不知道这一点,并且编译器可能会为该版本生成较慢的代码您尝试通过创建参考进行手动优化。
| 归档时间: |
|
| 查看次数: |
2603 次 |
| 最近记录: |