我正在阅读 Oreilly的学习XNA 4.0 ,我注意到作者很容易多次创建结构值,例如Vector2
或Rectangle
不考虑表现。
例如,检查两个游戏实体之间碰撞的SquareCollision()
方法每次调用时都会创建两个Rectangle
,而不是简单地让每个游戏实体都拥有自己的Rectangle
ValueType
}字段并比较字段而不创建任何更多的结构值。
我在很多地方已经多次看到这种模式,这让我很惊讶:
在C#中创建的结构值是否可以忽略不计?
这真的属于微优化部分吗?
也许是因为我的经验主要是Java,{{1}} s的概念对我来说很奇怪,但似乎从结构中重新创建一个值(并且多次调用它的构造函数)似乎是一个巨大的浪费资源。
答案 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();
}
}