Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 创建结构值的性能_C#_Struct_Xna - Fatal编程技术网

C# 创建结构值的性能

C# 创建结构值的性能,c#,struct,xna,C#,Struct,Xna,我目前正在阅读Oreilly的《学习XNA 4.0》,我注意到作者倾向于多次创建结构值,例如Vector2或Rectangle,而不考虑性能 例如,检查两个游戏实体之间冲突的SquareCollision()方法每次调用时都会创建两个矩形s,而不是简单地让每个游戏实体持有自己的矩形字段并比较字段,而不创建任何更多的结构值 我在许多地方多次看到这种模式,这让我感到好奇: 创建的结构值在C#?中可以忽略不计 这真的属于微优化部分吗? 也许因为我的经验主要是使用Java,ValueTypes的概念对我

我目前正在阅读Oreilly的《学习XNA 4.0》,我注意到作者倾向于多次创建结构值,例如
Vector2
Rectangle
,而不考虑性能

例如,检查两个游戏实体之间冲突的
SquareCollision()
方法每次调用时都会创建两个
矩形
s,而不是简单地让每个游戏实体持有自己的
矩形
字段并比较字段,而不创建任何更多的结构值

我在许多地方多次看到这种模式,这让我感到好奇:
创建的结构值在C#?中可以忽略不计
这真的属于微优化部分吗?


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

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

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

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

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


像往常一样,您需要分析它是否重要。

基本上,在(比如)网格
对象中包含该结构对您没有好处。因为在请求时,结构的值将被复制。考虑例子:

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
实例,在您实际需要它的时候,您可以快速地进行堆栈分配和垃圾收集


如果你对结构的性能不满意,可以考虑使用<代码>非安全< /COD>数据数组。但这是您应该衡量的,以便了解这是否适合您。

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

解决方案
我认为这有点难以描述,因为真正重要的是整体性能的影响。即使重新创建相同的值的速度比使用字段慢10000倍,但如果性能命中率仅为0.0001%,这仍然没有什么意义。(为这些随意的数字感到抱歉,只是试图确保我被理解。)我试图理解的是,这种做法到底有多糟糕(如果有的话),以及我是否应该避免这样做。通过展示代码,你可以让问题更具体一些。防止误解。我一直想知道其中的区别,例如
p点;p、 X=1;p、 Y=2
vs.
p=新点(1,2)
。也许对于编译器来说,这最终不会有什么不同。如果我只是使用公共字段而不是公共属性,这不是可以解决的吗?据我所知,结构属性在getter调用中创建结构的新副本。@acid:不,它不会改变任何东西。它不是关于访问方式属性/字段/函数返回参数,而是关于。如果您想在类中保存
向量
,可以尝试使用
ref
关键字传递它,例如
碰撞检测
。在这种情况下,不会复制该值,而是通过引用传递。但这也是你必须衡量的。如果
Vector
类不大,我会去寻找你已经看到的解决方案,所以在需要的时候分配。我不想问这样的问题,但什么是大的?一个
Vector2
可能不大,但是
Vector4
或者
Rectangle
呢?我想这只能通过分析来回答…好的答案可能是这个。在这种情况下,
Vector
只有3个浮点数
x
y
z
仍然是“可行的”:结构类型的属性通过返回整个结构来操作,即使读取结构的代码只是读取一个字段。结构类型的公共字段没有这个问题。请注意,一些古老的C#编译器允许写入返回的struct属性的字段(因为该属性的返回值只是一个temp,所以不会有任何效果)。当时,防止该问题的最佳方法是结构不允许任何写入字段的方式,构造函数除外。鉴于现代编译器不再允许对temp进行愚蠢的写入,……在我看来,唯一的解决方法是使用受保护/公共字段来确保始终使用相同的结构,而不是不必要地复制它。或者,如果使用
[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();
}

}