长寿命对象的结构与类

当你需要拥有非常小的物体时,比如说它包含2个浮动属性,并且你将拥有数百万个不会被“摧毁”的物体,结构是更好的选择还是类?

就像在xna中作为库一样,有point3s等作为结构但如果你需要长时间保持这些值,它会造成性能威胁吗?

与大多数关于结构的问题相反,这实际上似乎是对结构的良好使用。 如果它包含的数据是值类型,并且您将使用大量这些数据,那么结构将很有效。

一些技巧:

::结构不应大于16个字节,否则会失去性能优势。

::使结构不可变。 这使得使用更加清晰。

例:

public struct Point3D { public float X { get; private set; } public float Y { get; private set; } public float Z { get; private set; } public Point3D(float x, float y, float z) { X = x; Y = y; Z = z; } public Point3D Invert() { return new Point3D(-X, -Y, -Z); } } 

答案取决于最终存储对象/值的位置。 如果它们要存储在像ArrayList这样的无类型集合中,那么你最终将它们装箱。 Boxing为结构创建一个对象包装器,并且脚印与类对象相同。 另一方面,如果您使用类似T []或List的类型数组,那么使用结构只会存储每个元素的实际数据,仅包含整个集合的覆盖区而不是其元素。

因此,在T []数组中使用结构更有效。

最关心的问题是内存是在堆栈还是堆上分配的。 默认情况下,结构进入堆栈,并且堆栈通常在空间方面受到更多限制。 因此,像这样创建一大堆结构可能是个问题。

但在实践中,我并不认为这是一笔大交易。 如果你有很多这样的话,他们很可能是某个类实例(在堆上)的一部分。

Struct似乎适用于此应用程序。

请记住,“需要保留那些值”意味着它们存储在堆上的某个地方,可能是类实例的数组字段。

需要注意的一点是,这会导致在大对象堆上进行分配。 它不清楚如果有的话,这个堆如何对自己进行defrags,但对于很长时间存在的对象来说可能不是问题。

对于数百万这些数据类型使用类可能在解除引用的剪切量方面很昂贵,这种情​​况可能会发生在这种类型的操作上。

通常,相同类型的大型非别名(即非共享)数据最好存储在结构中以提高性能,因为您减少了间接数量。 (另请参见when-structs-the-answer )。 类和结构之间的确切性能差异取决于您的用法。 (例如,在操作中,你是否只访问结构的一部分?你做了很多临时复制吗?如果结构很小,它可能总是更好用,但如果它很大,创建临时副本可能会减慢你的速度。如果你使它不可变你将不得不总是复制整个东西来改变价值。)

如有疑问,请测量。

由于您对这种测量可能不明显的长期影响感兴趣,请注意这些数组可能存储在大对象堆上,应该重新使用而不是销毁和重新分配。 (参见CRL Inside Out:大型物体堆未被发现 。)

在调用中传递较大的结构时,您可能希望使用ref参数传递它们以避免复制。

值类型(struct)适用于未经常在堆上分配的类型,也就是说,它们主要包含在另一个引用或值类型中。

你给出的Vector3示例就是一个很好的例子。 你很少会在堆中悬挂Vector3,它们大部分时间都包含在一个本身在堆中的类型中,或者用作局部变量,在这种情况下,它将被分配在堆栈中。