Suppose I have this structures in c++
:
class A{
public:
B b;
}
class B{
public:
C c;
}
class C{
public:
double x;
double y;
double z;
double s;
function Usize(){
s = sqrt(pow(x,2) + pow(y,2) + pow(z,2));
}
}
Will accessing the the values in c
ten times require more memory traffic than creating a direct pointer to c and use it? In code terms (assuming legal values):
double dx = 2*rand()-1;
double dy = 2*rand()-1;
double dz = 2*rand()-1;
a->b->c.x *= dx;
a->b->c.y *= dy;
a->b->c.z *= dz;
if (a->b->c.x > 10) a->b->c.x -= 10;
else if (a->b->c.x <0) a->b->c.x += 10;
if (a->b->c.y > 10) a->b->c.y -= 10;
else if (a->b->c.y < 0) a->b->c.y += 10;
if (a->b->c.z > 10) a->b->c.z -= 10;
else if (a->b->c.z < 0) a->b->c.z += 10;
a->b->c->Usize();
vs.
double dx = 2*rand()-1;
double dy = 2*rand()-1;
double dz = 2*rand()-1;
C* ac = a->b->c
ac.x *= dx;
ac.y *= dy;
ac.z *= dz;
if (ac.x > 10) ac.x -= 10;
else if (ac.x < 0) ac.x += 10;
if (ac.y > 10) ac.y -= 10;
else if (Ac.y < 0) ac.y += 10;
if (ac.z > 10) ac.z -= 10;
else if (ac.z < 0) ac.z += 10;
Thanks.
In this exact case, a good compiler should be able eliminate the common expression and generate pretty much optimal code. Since you're accessing primitive types, a->b->c can be evaluated once and used throughout the method.
The call to C::USize() or access of a non primitive type in "class C" will break this pattern and force the compiler to re-evaluate a->b->c for the next line.
This is because the compiler cannot make 100% sure that a method call/operator does not change a, a.b or b.c, so it has to re-evaluate the chain to make sure.
I'd almost call worrying about this at this stage premature optimization. That said, your second example is both more readable and helps the compiler not have to second guess in case you insert any method calls later, so I'd go for that.