创建结构值的性能

时间:2012-02-12 22:27:35

标签: c# struct xna

我正在阅读 Oreilly的学习XNA 4.0 ,我注意到作者很容易多次创建结构值,例如Vector2Rectangle不考虑表现。

例如,检查两个游戏实体之间碰撞的SquareCollision()方法每次调用时都会创建两个Rectangle,而不是简单地让每个游戏实体都拥有自己的Rectangle ValueType }字段并比较字段而不创建任何更多的结构值。

我在很多地方已经多次看到这种模式,这让我很惊讶:
在C#中创建的结构值是否可以忽略不计?
这真的属于微优化部分吗?

也许是因为我的经验主要是Java,{{1}} s的概念对我来说很奇怪,但似乎从结构中重新创建一个值(并且多次调用它的构造函数)似乎是一个巨大的浪费资源。

3 个答案:

答案 0 :(得分:6)

在堆栈上创建一个简单使用的结构非常便宜,并且与仅为所有这些值设置局部变量并没有太大区别,但是使用了组件化。但是,作为对象的一部分,它将是每个对象的相同数据的附加副本。

两种方法都有效,具体取决于方案。然而,在堆栈上,没有真正的资源成本。作为对象的一部分,您需要确保不会不必要地复制数据,因为这会产生实际成本。

如果它是对象的属性,则需要多次复制。

如果它是一个对象上的字段,是的:它可以在没有复制的情况下就地使用,但是:在大多数情况下这个相对较小。

与往常一样,您需要了解是否重要。

答案 1 :(得分:1)

在你的(说)Mesh对象中包含该结构的东西基本上不会对你有益。在请求它的时候,结构的值将被复制。考虑一下例子:

public class Mesh 
{
  public Vector3 MeshCogVector {get;set};
}

以及您拥有的代码中的某个地方

public void CollisionDetection
{
    for(int i=0;....)
    {
       Mesh curmesh = listofmashes[i];
       Vector3 vec3 = curmesh.MeshCogVector; //value copied

    }
}

因此,在您的条件下以这种方式使用,您基本上没有任何好处+您增加了Mesh实例大小。

而是在实际方法中使用/构造Vector3实例,在您实际需要它的那一刻,您可以快速进行堆栈分配和快速垃圾收集。

如果您对结构中的性能不满意,可以考虑使用non safe数据数组。但这是你应该测量的东西,以便了解这是否适合你。

答案 2 :(得分:0)

结构中存在的所有属性作为连续的内存分配在内存中存在,这意味着所有属性并排出现,因此访问每个属性,结构使CPU变得简单。遵循以下核心OPP概念可能会降低性能,例如          在类中,如果您具有var Power,则在其他脚本中,如果您正在引用此值,则CPU会引用该类中存在的属性的所有位置(由于所有数据都在堆上存在于随机位置,因此需要做更多的工作以供CPU使用)作为行缓存。

解决方案

[System.Serializeable]
public Struct SomeclassData(){  

Vector3 vec;
float value;
// some numeric data or vector data  }


public class SomeClass : Monobehaviour{
SomeclassData data;

void Start(){
 data = new SomeClassData();
}

}