Tim*_*uri 17 .net memory-management data-structures
由于结构是值类型,因此在将数据作为参数传递给方法时会复制它们的数据.例:
int someInt = 7;
DoSomeMethod(someInt); // <-- This is passing the "value" 7.
Run Code Online (Sandbox Code Playgroud)
到目前为止,很容易理解,你可能想知道我的问题是如何有效的......所以请考虑以下几点:
public struct TimmysStructOfGoodness
{
public int SomeInt1;
public int SomeInt2;
public int SomeInt3;
// ... later that day ...
public int SomeInt999;
}
Run Code Online (Sandbox Code Playgroud)
然后,参考以下代码:
TimmysStructOfGoodness someStructOfGoodness = new blah blah blah...
DoSomeMethod(someStructOfGoodness); // <-- **HERE IS WHERE THE QUESTION APPLIES!**
Run Code Online (Sandbox Code Playgroud)
上面的语句是否试图分配几个内存来"复制"我的值类型(struct)?
如果答案是肯定的 - 那么何时/哪里是"更快"和"更慢"之间的界线?
如果不是 - 那为什么不呢?因为我所知道的价值类型,这应该是一个问题.
主要免责声明:我知道这与你为什么要使用一个类的结构无关,而且我知道我永远不会用999个字段创建一个结构 - 这只是一个基本的内部和内部等问题: )
yu_*_*sha 14
(更新,感谢其他用户的贡献)
与类不同,struct是在堆栈上创建的.因此,实例化(和销毁)结构比使用类更快.
除非(正如Adam Robinson指出的那样)struct是一个类成员,在这种情况下,它与堆中的所有其他内容一起分配.
另一方面,每次分配结构或将其传递给函数时,都会复制它.
我不认为结构大小有一个硬性限制.成千上万的字节肯定太多了.MSDN 说:
除非您需要引用类型语义,否则系统可以更有效地将小于16字节的类作为结构进行处理.
这是 - 如果你需要通过引用传递它,使它成为一个类,无论大小.
在第二个想法中,您仍然可以通过在函数参数列表中指定ref来通过引用传递struct.
因此,如果通过引用传递它并将其用作类成员,那么大型结构实际上可以正常.
结构和类不仅具有不同的性能,它们的行为也不同.您应该使用最适合您正在实现的类型的那个.在MSDN上清楚地描述了何时使用其中一个或哪一个的指南.仅当以下所有条件适用时才使用结构:
如果要将结构传递给函数,您将获得它的副本.如果你的结构很大,那么它将导致复制大量数据.引用通常实现为4个字节(在x86上),因此传递对象只需要复制这4个字节.
另请注意,上述指南要求结构很小.
结构的性能影响取决于您如何使用这些结构.
关于结构是否比参考类型更快或更慢,不可能做出明确的陈述.这一切都取决于你如何使用它们,以及在什么情况下.
结构(一般的值类型)最终可以在堆栈或堆上分配 - 具体取决于它们的声明上下文.如果在方法的主体中声明它(并且没有明确地将其封装),结构将最终在堆栈上.如果然后将该结构传递给按值接受它的方法(如在您的示例中),它确实将被复制 - 但在堆栈上.堆栈上的分配是一个非常有效的过程(BTW,.NET堆也非常有效) - 但它是一个复制过程.
当然,您可以使用ref/out传递结构 - 在这种情况下不会发生复制 - 对结构的引用将传递给方法.这可能是,也可能不是,因为它将允许被调用的方法改变结构的内容.
声明为类成员的结构实际上将在堆上分配(作为类的内存布局的一部分).如果您传递该类,则不会复制该结构,但仍可通过类引用访问该结构.
您还可以通过显式装箱来获取堆上的结构:
object x = new MyStruct( ... ); // boxed on the heap
Run Code Online (Sandbox Code Playgroud)
Jon Skeet有一篇很好的文章,关于你应该阅读的内存最终的内容.
归档时间: |
|
查看次数: |
5079 次 |
最近记录: |