gpt4 book ai didi

c - 访问 C 中的结构成员有多快?

转载 作者:行者123 更新时间:2023-12-04 00:52:20 26 4
gpt4 key购买 nike

访问结构成员的过程是否比访问直接变量慢?如果我在多个地方使用了相同的结构成员,我应该在变量中声明它并将其保存在那里以节省多次访问同一成员的成本吗?我应该重复Struct.Member Struct.Member Struct.Member或者我应该将它保存在变量int Member = Struct.Member 中吗? Member Member Member ?在什么时候我应该使用后者而不是前者?如果这些成员是位域怎么办?

最佳答案

虽然访问结构成员与分配“直接”对象存在一些复杂性,但您的方案中更重要的区别是编译器可能能够更好地优化局部变量的使用而不是结构成员的使用通过了。
这是因为结构通常是通过指针(即参数或来自另一个结构的指针)间接传递的。考虑这段代码:

struct S { int a; };

void baz(int);

void foo(struct S *s)
{
baz(s->a);
baz(s->a);
}

void bar(struct S *s)
{
int a = s->a;
baz(a);
baz(a);
}
bar ,编译器知道 baz无法更改 a , 因为 a是一个从不使用其地址的局部变量。因此,编译器可以加载 s->a从内存中一次并将其传递给 baz两次。
foo ,编译器无法知道 baz不变 s->a , 因为 baz可以通过某种方式访问​​ s->a例如通过存储在外部对象中的地址。因此,它必须加载 s->a在第一次调用 baz 之前并再次在第一次通话和第二次通话之间。
使用启用了优化的 Apple Clang 11.0.0 进行测试证实了这一点;为 foo 生成的汇编代码例程包含两个负载 s->a来自内存,而 bar 的代码只包含一个。
尽管这经常发生在结构中,因为结构通常是通过地址传递的,但这并不是作为结构成员的固有结果。此代码中出现相同的问题:
void baz(int);

void foo(int *p)
{
baz(*p);
baz(*p);
}

void bar(int *p)
{
int a = *p;
baz(a);
baz(a);
}
即使没有调用子程序,它也可能发生;参数可以“干扰”其他参数。在以下代码中, foo必须重新加载 z->a但是 bar不需要。即使 z符合 const ,分配给 x可能会改变它:
struct S { int a; };

void foo(struct S *x, struct S *y, const struct S *z)
{
x->a = z->a;
y->a = z->a;
}

void bar(struct S *x, struct S *y, const struct S *z)
{
int a = z->a;
x->a = a;
y->a = a;
}

关于c - 访问 C 中的结构成员有多快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65625674/

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