我在C#中创建一个几何库,我将需要以下不可变的类型:
Vector2f
(2 float
s - 8字节)Vector2d
(2 double
s - 16 bytes)Vector3f
(3 float
s - 12个字节)Vector3d
(3 double
s - 24字节)Vector4f
(4 float
s - 16 bytes)Vector4d
(4 double
s - 32字节)我正在尝试确定是否使它们成为结构或类。 MSDN建议只使用结构,如果大小不超过16个字节。该引用似乎是从2005年开始的.16个字节仍然是最大建议大小吗?
我确信使用float
向量的结构比使用类更有效,但我应该如何处理double
向量?我是否应该使它们的结构一致,或者我应该让它们上课?
更新: 看起来每个人都同意他们应该是结构。谢谢你的答案。
答案 0 :(得分:8)
答案 1 :(得分:4)
我通常会制作类似这些结构的类型。结构更可能放在堆栈上,如果你使用数组,你可以获得比使用List<>更好的性能。对象只要您远离可能导致您的矢量类被装箱的操作,结构通常将是更高性能的方式。
答案 2 :(得分:4)
不可变的结构是一个不错的选择。 MSDN上的大小建议是最弱的,32字节并不是很大。
主要论点是,Vector用作简单(数字)类型,而值类型的实现最合适。
一个很好的并行是dotNet 4中新的复杂和 BigInteger 结构
答案 3 :(得分:3)
绝对是结构。为什么?嗯,这是我猜的部分感觉,矢量只是感觉和行为就像值。
Rico Mariani here给出了为API的某些类型选择值类型的一些原因(我不认为这是他正在讨论的XNA)。
虽然效率是这里的一个因素,但我认为这不是垃圾收集,而是像Rico所说的更多关于数据密度。假设您还有一个Vertex
类型,其中包含两个Vector3
s:法线为Vector3
,世界坐标为Vector3
。如果您创建了这些类型类,那么拥有包含100个Vertex
元素的数组将包含:
Vertex
元素的数组中的指针)Vertex
到两个Vector3
元素的指针)Vector3
类付费的8字节开销)float
3 Vector3
的实际有效负载6000字节(在32位系统上)。
作为值类型,它只是200 * 12字节= 2400字节。在阅读数组时,更不用说低级别的间接空间,这样更有效。
但占用大量空间并不一定会使它变慢,使用错误的值类型可能比使它成为类更慢,如I have found out。你肯定希望尽可能地通过ref
传递它们,避免复制它们,但这不适用于所有操作,所以测量。我想我记得在通过ref
时计算点积较慢,也许是因为它通过使IL变大来某种程度上防止了内嵌。但是不要接受我的话,只是衡量。
答案 4 :(得分:2)
在我看来,我会选择结构,因为它们会被大量分配到堆栈上,这样可以减轻GC的压力,使应用程序运行得更顺畅。
一个提示,你的方法可能会将参数作为ref和out参数,这会减少传递和返回结构时发生的数据的复制量。
答案 5 :(得分:2)
我们最近将一些数学类型(vec3,vec4,matrices等)转换为使用结构而不是类,并且在基准测试中稍微快一点,它也降低了GC压力(我们有数百兆的Vec3通过CLR分析器发现的相对较短时间内的分配。
值得注意的是,Xna实现了Vectors&amp ;;矩阵使用结构完成。如果您担心性能,也可以随时通过引用传递。
答案 6 :(得分:0)
我认为你担心性能?
如果它们是不可变的,它们应该在行为上相同。只需使用一个,如果事实证明存在性能问题,请稍后再切换。
如果你的目标是.NET CE,你应该考虑使用结构,因为GC不如完整的.NET实现那么高效。
答案 7 :(得分:-1)
结构(通常)存储在堆栈中,可能使它们更有效,但可能不足以产生明显的差异。