pointers for speed
Chris Torek
torek at elf.ee.lbl.gov
Tue Feb 26 10:47:21 AEST 1991
(This is a topic for comp.lang.c, not comp.std.c; I have redirected
followups there.)
In article <1998 at gold.gvg.tek.com> shaunc at gold.gvg.tek.com (Shaun Case) writes:
>I know that when you repeatedly access something like
>
>foo.a.b.c.d[11].value
>
>it is better to declare a (register) pointer, assign it the address
>of foo.a.b.c.d[11].value, and do manipulations on that, since it
>is faster.
This is an unsupported assertion, and in fact it often turns out to
be no faster (though usually no slower either).
In particular, given ...
>a heavily nested structure ...
>I want to access the various members of a.x.something (.foo, .foo2,
>.blah, .blah2) quickly.
... structures that are nested in this manner (where variable `a' is
a structure containing a member `x' which itself is a structure
containing a member `something' which itself is a structure containing
members `foo', `foo2', etc.) are typically implemented such that
computing &a.x.something.foo requires exactly as much work as computing
&a.x or &a.x.something. For instance, on the 68010, the difference
between:
a.x.something.foo = 3;
and:
local_var = 3;
is, in essence,
moveq #3,a5 at 260
and
moveq #3,a7 at -32
both of which require exactly the same amount of time and space.
On the other hand, writing
ptr->x.something.foo = 3;
ptr->x.something.foo2 = 3 * 3;
ptr->x.something.blah = "headache";
is generally perceived to be less clear than writing:
s->foo = 3;
s->foo2 = 3 * 3;
s->blah = "headache";
and if you agree, you should use the latter.
>I have a function that I pass a pointer to type struct a, thus:
>
>void do_stuff (struct *a ptr)
>{}
>
>and what I want to do is something like
>
>register char *fastptr;
>
>fastptr = &(ptr->x.something)
>
>and then access fastptr->foo, fastptr->foo2, etc.
It would help greatly if your examples were legal C....
To take the conceptual error first: Declaring `fastptr' as `register
char *fastptr' means that `fastptr' points to `char's. It does not
point to structures. Since it does not point to structures, you may
not use it to obtain elements of structures. If you want a pointer
to point to one or more structures of type `struct glorp', you must
declare it as a pointer to `struct glorp':
struct glorp *g;
Next, if `ptr' is to point to a `struct a', the proper syntax is:
void do_stuff(struct a *ptr)
Composing these and adding the assignment to make `g' point to the
glorp member of the structure to which `ptr' points, we get:
void do_stuff(struct a *ptr) {
struct glorp *g;
g = &ptr->x.something;
At this point you can use `g->foo', `g->foo2', and so on exactly
as above. It will likely be no faster (but more readable and/or
less cumbersome) than using `ptr->x.something.foo', etc.
On the other hand, if `ptr' were to point to a structure in which the
sub-structures are not directly imbedded, but rather found through
pointers, then:
void do_stuff(struct object *o) {
struct value *v;
/*
* Pick up object's current value pointer,
* which is found by reading its attributes
* to find its current binding, and then
* reading the binding to find the current value.
*/
v = o->o_attr->a_binding->b_value;
...
}
in this case using `v' is more likely (but still not guaranteed!) to
be faster than writing `o->o_attr->a_binding->b_value' each time. It
is also almost certain to make those editing the code happier.
--
In-Real-Life: Chris Torek, Lawrence Berkeley Lab EE div (+1 415 486 5427)
Berkeley, CA Domain: torek at ee.lbl.gov
More information about the Comp.lang.c
mailing list