user14629932
user14629932

Reputation:

How fast is accessing a struct member in C?

Is the process of accessing a struct member any slower than accessing a direct variable? If I have the same struct member used in multiple places, should I declare it in a variable and save it there to spare the cost of accessing the same member multiple times? Should I repeat Struct.Member Struct.Member Struct.Member or should I save it in a variable int Member = Struct.Member Member Member Member? At which point should I use the latter instead of the former? What if those members are bit fields?

Upvotes: 8

Views: 2594

Answers (3)

P.Fiery
P.Fiery

Reputation: 11

I can tell you that in using GNU C and writing code to a Cortex M33 using the highest available optimization setting, pulling a value out of an array before using it in a 'for' loop saved a few cycles. I would expect that the compiler treats a structure much like an array, so it probably would likewise speed things up, but very slightly.

The code I'm writing must execute AFAP so I measure everything. Measuring is probably the only way to know for sure. Beware when measuring code with high optimization settings though. If you test something where the result is going nowhere, the optimizer will often not bother running the inner loops. I use a scope and an IO pin to measure timing. Making the IO state depend on the result solves this problem... usually ;)

Upvotes: 0

Eric Postpischil
Eric Postpischil

Reputation: 224092

While there are some complications involving accessing a structure member versus allocating a “direct” object, a more important difference in your scenario is that a compiler may be able to better optimize uses of a local variable than uses of a member of a structure it is passed.

This is because structures are commonly passed indirectly, by a pointer (that is either a parameter or a pointer from another structure). Consider this code:

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);
}

In bar, the compiler knows that baz cannot change a, because a is a local variable whose address is never taken. Therefore, the compiler can load s->a from memory once and pass it to baz twice.

In foo, the compiler cannot know that baz does not change s->a, because baz could have some way of accessing s->a such as through an address stored in an external object. Therefore, it has to load s->a before the first call to baz and again between the first call and the second call.

Testing with Apple Clang 11.0.0 with optimization enabled confirms this; the assembly code generated for the foo routine contains two loads of s->a from memory, while the code for bar contains only one.

Although this occurs frequently for structures since structures are commonly passed by address, this is not inherently a consequence of being a structure member. The same issue occurs in this code:

void baz(int);

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

void bar(int *p)
{
    int a = *p;
    baz(a);
    baz(a);
}

It can also occur even if no subroutine is called; parameters can “interfere” with other parameters. In the following code, foo must reload z->a but bar does not need to. Even though z is qualified with const, the assignment to x might change it:

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;
}

Upvotes: 6

Lundin
Lundin

Reputation: 214880

There is no reason why a struct member access would be slower than a plain variable.

There might be a few special case exceptions to that, like when you have a pointer to struct, and the compiler has to go through the pointer to get to the data. Then you get indirect access, which is generally a tiny bit slower than direct access. But micro-optimizations like that isn't something you should worry about when writing code.

Generally, focus on writing readable code and you usually get fast code at the same time. Beginners trying to manually optimize code and thereby turning it into an unholy mess is a common problem. Manual code optimization is very qualified work and not something you should be worrying about until you have some 10+ years of programming experience.

Upvotes: 3

Related Questions