我应该在C#中创建这些向量类或结构

时间:2010-04-18 20:25:56

标签: c# class struct performance size

我在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向量?我是否应该使它们的结构一致,或者我应该让它们上课?

更新: 看起来每个人都同意他们应该是结构。谢谢你的答案。

8 个答案:

答案 0 :(得分:8)

Microsoft的XNA Framework使用其Vector2 / 3 / 4数据类型的结构。这些包含float类型的字段。我也没有看到做同样的事;使用double类型的字段不应该有很大的不同。

答案 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元素的数组将包含:

  • 100 * 8字节(我认为8字节是内存中类的开销,类型标题是4字节,其他东西是4字节,是GC句柄吗?)
  • 100 * 4字节(对于Vertex元素的数组中的指针)
  • 200 * 4字节(用于从每个Vertex到两个Vector3元素的指针)
  • 200 * 8字节(用于使Vector3类付费的8字节开销)
  • 200 * 12字节(对于每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)

结构(通常)存储在堆栈中,可能使它们更有效,但可能不足以产生明显的差异。

http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.aspx?ArticleID=9adb0e3c-b3f6-40b5-98b5-413b6d348b91