使用new运算符创建类的实例时,将在堆上分配内存.当您使用new运算符创建结构的实例时,在堆上还是堆栈上分配内存?
我们已经在SO中看到了很多关于c#中的类vs结构的讨论.最后得出的结论是它的堆/堆内存分配.并建议在小型数据结构中使用结构.
现在我有一种情况来决定这两种选择中的简单数据存储.在我们的应用程序中,我们有数千个类,只是作为简单的数据存储(仅暴露的公共字段),它们在不同的模块和服务之间传递.
根据我的理解,出于性能原因,我觉得最好继续使用struct而不是类.因为这些是简单的数据结构,所以只能充当数据存储.
在继续这一过程之前,我需要经历过这场斗争的人们的一些专家建议.
当你需要拥有非常小的物体时,比如说它包含2个浮动属性,并且你将拥有数百万个不会立即被"摧毁"的物体,结构是更好的选择还是类?
就像在xna中作为库一样,有point3s等作为结构但是如果你需要长时间保持这些值,它会造成性能威胁吗?
在诸如此类的情况下,在结构上使用类是否有任何优势?(注意:它只会保存变量,永远不会有函数)
class Foo {
private:
struct Pos { int x, y, z };
public:
Pos Position;
};
Run Code Online (Sandbox Code Playgroud)
与:
struct Foo {
struct Pos { int x, y, z } Pos;
};
Run Code Online (Sandbox Code Playgroud)
类似的问题:
为了在现有的软件框架中进行优化,我进行了独立的性能测试,因此我可以在花费大量时间之前评估潜在的收益.
有N不同类型的组件,其中一些实现了IUpdatable接口 - 这些是有趣的.它们分组在M对象中,每个对象都维护一个组件列表.更新它们的方式如下:
foreach (GroupObject obj in objects)
{
foreach (Component comp in obj.Components)
{
IUpdatable updatable = comp as IUpdatable;
if (updatable != null)
updatable.Update();
}
}
Run Code Online (Sandbox Code Playgroud)
我的目标是为大量分组对象和组件优化这些更新.首先,确保连续更新一种类型的所有组件,方法是将它们缓存在每种类型的一个数组中.基本上,这个:
foreach (IUpdatable[] compOfType in typeSortedComponents)
{
foreach (IUpdatable updatable in compOfType)
{
updatable.Update();
}
}
Run Code Online (Sandbox Code Playgroud)
它背后的想法是,JIT或CPU可能比在洗牌版本中一次又一次地在相同的对象类型上操作更容易.
在下一步中,我希望通过确保一个Component类型的所有数据在内存中对齐 - 通过将其存储在结构数组中来进一步改善这种情况,如下所示:
foreach (ComponentDataStruct[] compDataOfType in typeSortedComponentData)
{
for (int i = 0; i < compDataOfType.Length; i++)
{
compDataOfType[i].Update();
}
}
Run Code Online (Sandbox Code Playgroud)
在我的独立性能测试中,这些变化都没有显着的性能提升.我不知道为什么.没有显着的性能提升意味着,10000个组件,每个批处理运行100个更新周期,所有主要测试大约需要85毫秒+/- …
请查看这两个小例子:
public struct Struct
{
public readonly string StringValue;
public readonly int IntValue;
public Struct(string stringValue)
{
this.StringValue = stringValue;
this.IntValue = this.StringValue.GetHashCode(); // Just ignore this assignment, please :).
}
}
public class Class
{
public readonly string StringValue;
public readonly int IntValue;
public Class(string stringValue)
{
this.StringValue = stringValue;
this.IntValue = this.StringValue.GetHashCode(); // Just ignore this assignment, please :).
}
}
Run Code Online (Sandbox Code Playgroud)
据我所知,如果我将 struct 作为参数传递,它将制作它的副本someObject.Method(this.cachedStruct);- 这反过来将制作 a 的副本,StringValue因为strings 是不可变的,它将在内存中为该字符串分配数组,这是非常昂贵的操作 [请原谅我,如果我犯了一个错误,请在这种情况下纠正我]。
因此,在这种情况下,我认为使用 的实例Class …