This question has to do with best practices… please do not confuse it with premature optimization.
I noticed in .Net that deep object referencing takes quite some time to process when compared to flat or shallow objects. For example:
object1.object2.object3.object4.Property
… is not efficient since, I conclude, each object has to be de-referenced along the path. This is in contrast to C, where Property‘s memory ref would be calculated by the compiler, rather than at run time.
Now, we obviously wouldn’t take all the fields of object2+ and flatten them into object1 just for speed. The coding would be unwieldy and hard to manage. But the speed difference could be significant.
So my question is, “What is the best practice in building deep objects vs. flat(ish) objects?” And, further, is there any advantage to using structs where one is simply trying to group a number of fields together, such as:
public struct SizeData
{
public long Written;
public long Read;
public int Size;
}
The two questions relate.
EDIT
To illustrate:
public class Leaf
{
public int Property;
}
public class Depth1
{
public Leaf Leaf;
}
public class Depth2
{
public Depth1 Depth1;
}
public class Depth3
{
public Depth2 Depth2;
}
private void button12_Click(object sender, EventArgs e)
{
Depth3 depth = new Depth3();
depth.Depth2 = new Depth2();
depth.Depth2.Depth1 = new Depth1();
depth.Depth2.Depth1.Leaf = new Leaf();
Leaf leaf = new Leaf();
var T1 = Environment.TickCount;
for (int i = 0; i < 100000000; i++)
{
depth.Depth2.Depth1.Leaf.Property++;
}
var T2 = Environment.TickCount;
for (int i = 0; i < 100000000; i++)
{
leaf.Property++;
}
var T3 = Environment.TickCount;
MessageBox.Show((T2 - T1).ToString() + Environment.NewLine +
((T3 - T2).ToString()));
}
The only concern here IMHO is not speed, but dependency. Have you ever tried to refactor an application that frequently uses deep object nesting like this? It’s a pain in the arse. Have a look at the Law of Demeter (or as I say, the Guideline of Demeter). The idea is that instead of using
you instead use something like
to avoid a dependency on the Address object. Is it faster? Maybe, if you implement it right. But I personally don’t care because the speedup is really trivial. All I care about here is reducing dependencies.