与指针相比,链式 public 成员访问的性能

Performance of chained public member access compared to pointer

因为我找不到任何关于链式成员访问的问题,而只有链式函数访问,所以我想问几个关于它的问题。

我有以下情况:

for(int i = 0; i < largeNumber; ++i)
{
  //do calculations with the same chained struct:
  //myStruct1.myStruct2.myStruct3.myStruct4.member1
  //myStruct1.myStruct2.myStruct3.myStruct4.member2
  //etc.
}

显然可以使用指针将其分解:

MyStruct4* myStruct4_pt = &myStruct1.myStruct2.myStruct3.myStruct4;
for(int i = 0; i < largeNumber; ++i)
{
  //do calculations with pointer:
  //(*myStruct4_pt).member1
  //(*myStruct4_pt).member2
  //etc.
}

成员访问 (.) 和函数访问之间是否有区别,例如 returns 指向私有变量的指针?

Will/Can 第一个示例由编译器优化,这是否强烈依赖于编译器?

如果在编译期间没有进行优化,will/can CPU 优化行为(例如将其保存在 L1 缓存中)?

链式成员访问在性能方面是否完全不同,因为变量在编译期间 "wildly reassigned" 无论如何?

我恳请不要讨论关于代码的可读性和可维护性的问题,因为对于我来说,链式访问更清晰。

更新: 一切都在一个线程中 运行。

这是您正在修改的常量偏移量,现代编译器会意识到这一点。

但是 - 不要相信我,让我们问问编译器(参见 here)。

#include <stdio.h>

struct D { float _; int i; int j; };

struct C { double _; D d; };

struct B { char _; C c; };

struct A { int _; B b; };

int bar(int i);
int foo(int i);

void foo(A &a) {
  for (int i = 0; i < 10; i++) {
    a.b.c.d.i += bar(i);
    a.b.c.d.j += foo(i);
  }
}

编译为

foo(A&):
    pushq   %rbp
    movq    %rdi, %rbp
    pushq   %rbx
    xorl    %ebx, %ebx
    subq    , %rsp
.L3:
    movl    %ebx, %edi
    call    bar(int)
    addl    %eax, 28(%rbp)
    movl    %ebx, %edi
    addl    , %ebx
    call    foo(int)
    addl    %eax, 32(%rbp)
    cmpl    , %ebx
    jne .L3
    addq    , %rsp
    popq    %rbx
    popq    %rbp
    ret

如您所见,在以下两种情况下,链接都已转换为单个偏移量:28(%rbp)32(%rbp)