这个问题与最佳实践有关...请不要将其与过早优化混淆。
我在.Net中注意到,与平面或浅层物体相比,深度物体参考需要相当长的时间来处理。例如:
object1.object2.object3.object4.Property
...效率不高,因为我得出结论,每个对象都必须沿着路径去引用。这与C形成对比,其中Property
的内存引用将由编译器计算,而不是在运行时计算。
现在,我们显然不会占用object2 +的所有字段,只是为了速度而将它们展平为object1。编码很笨重,难以管理。但速度差异可能很大。
所以我的问题是,“构建深对象与平坦(ish)对象的最佳做法是什么?”而且,使用结构体是否有任何优势,只需要将多个字段组合在一起,例如:
public struct SizeData
{
public long Written;
public long Read;
public int Size;
}
这两个问题有关。
修改
举例说明:
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()));
}
答案 0 :(得分:3)
在我看来,在你意识到这是一个瓶颈之前,你不应该考虑速度。
类/结构应该纯逻辑地分组:如果你看到某个类是是其他类的一部分,那么在更大的类中只需要 并且在更大的类中只有 ,然后你应该把它放在那里,从而避免污染命名空间。如果您看到较小的类在较大的类之外有用,请在外部定义它。那很简单。
总结:将你的班级/结构置于最深的适当水平,但不要更深。
示例:
myCar.RegistrationDate.Year.IsLeap
非常有意义,并且优于myCar.IsRegistrationYearLeap
point.Coordinates.Cartesian.X
没有多大意义,point.X
要好得多。答案 1 :(得分:3)
术语嵌套类通常用于表示“嵌套类型”。
class Foo
{
private class FoosHelper { .. }
}
这里最好的做法是谨慎使用它们,而不是私密。
但是你的例子不是关于嵌套类,而是关于嵌套对象:
object1.object2.object3.object4.Property
最佳实践是:首先建立一个逻辑性和内聚性的对象模型。
你对'扁平'的建议似乎是为了牺牲核心架构以进行微小的优化。不是一个好主意。
和(仅略微)相关的结构问题:
使用结构体是否有任何优势,只需要将多个字段组合在一起
不,通常不会。在极少数情况下,您需要非常大的小型数组,但通常使用结构只会带来缺点。
答案 2 :(得分:3)
这里唯一的担心恕我直言不是速度,而是依赖。您是否曾尝试重构经常使用此类深层对象嵌套的应用程序?这是一个痛苦的屁股。看看Law of Demeter(或者我说的是德米特指南)。这个想法是代替使用
person.Address.ZipCode
你改用
之类的东西person.AddressZipCode
以避免依赖于Address对象。它更快吗?也许,如果你正确实施它。但我个人并不在乎,因为加速非常微不足道。我在这里关心的是减少依赖性。
答案 3 :(得分:1)
结构字段将没有单独的内存分配,然后是封闭对象,所以没有差别,如果所有嵌套都是结构,它由编译器计算。
如果嵌套引用类型,则必须取消引用它们,这与C ++没有任何区别。