【发布时间】:2015-10-23 16:54:04
【问题描述】:
结构是值类型,因此每次对结构进行操作时都会完全复制。由于它们是值类型,因此结构被分配在堆栈中而不是堆中。
当结构作为参数传递时,我可以看到结构如何降低方法的性能,因为它们总是会被复制到堆栈中,特别是当它们很大并且有很多内部字段时。
但我很好奇 C# 如何处理结构的返回。
在 C 中,返回是通过寄存器进行的,或者如果要返回的值对于寄存器来说太大,则使用堆进行引用。几乎所有的 C# 结构教程都说结构存在于堆栈中,而不是堆中。
所以在下面的代码中:
MyStruct ms = GetMyValue();
GetMyValue() 在哪里
MyStruct GetMyValue();
C# 将如何处理 ms 变量的结构返回?特别是如果它对于寄存器来说太大了?它实际上是否会将其复制到堆中,然后再次将其复制回方法的调用者并将其分配给 ms?
编辑:
解决帖子中留下的cmets:
在发布这篇文章之前,我已经阅读了一些关于 C# 结构的教程,this tutorial 特别是使用了
stack这个词的次数比我数的还要多。而this MSDN tutorial 也谈到了堆栈,虽然它是从 2003 年开始的,但我认为从那时起结构没有改变。我知道这可能与 C# 完全无关,但实际上是 JIT 编译器本身或 CLR 或其他我不知道的问题。这就是我提出问题的目的,以便更多地了解 C# 的内部工作原理,即使这实际上与语言本身无关。
-
有C函数调用约定,对我的帖子最好的支持是this StackOverflow post。当我第一次在这里发布它时,我只是说出了我记得的内容,但是由于 SO 答案说:
至于您的具体问题,这取决于 ABI。有时如果返回值大于 4 字节但不大于 8 字节,可以拆分为 EAX 和 EDX。但大多数时候调用函数只会分配一些内存(通常在堆栈上),并将指向该区域的指针传递给被调用函数。
我可能在这个问题上错了,我说可能,因为答案说通常。
-
我想了解如何处理结构的真正原因是因为我有一个项目,我必须多次读取串行端口来轮询数据,这些数据将由方法返回。
由于数据只是一些字节,我认为我可以从结构中获得一些性能,而不是使用类来抽象串行端口传入的字节,但如果
return将struct作为堆传递我对性能提升的期望可能是错误的。是的,我可以做一个简单的测试并比较性能,我知道,但我想真正了解它是如何在幕后完成的,而不仅仅是记住我的模拟结果。我想知道我所使用的东西是如何工作的,而不仅仅是学习如何使用它们。
【问题讨论】:
-
And practically all C# struct tutorials say structs lives in the stack, never in the heap.他们不都这么说。任何这样做都是完全错误的。In C the return is made by registers, or by reference using the heap不,堆永远不会用于将返回值传递给调用者。 -
它可能会便宜一点,但总是复制一个值类型以获得回报。要有效地使用结构,您需要使用 ref/out 参数。提示:使用类。如果不确定,请对结构进行基准测试。几乎不花时间。
-
我不明白投反对票的意义。当有人试图学习一些你能做的一切时?即使他在很多地方都错了,你也不应该投反对票。我不是说我知道这一点。我也在学习,但最好说出拒绝投票的原因。
-
不是一个完全的骗局,但这个related question 的答案会让你明白。
-
这个问题中几乎每个句子都是假的。以如此多的谎言为基础的问题很难回答。
标签: c# class struct clr return-value