我可以看出当结构体作为参数传递时,它们会被始终复制到堆栈中,特别是当它们具有许多内部字段时,这可能会降低方法的性能。
但我很好奇 C# 如何处理结构体的返回。
在 C 中,返回值是通过寄存器或使用堆引用来返回的,如果要返回的值太大,则使用堆。实际上,几乎所有 C# 结构体教程都说结构体存在于堆栈中,从不在堆中。
因此,在以下代码中:
MyStruct ms = GetMyValue();
其中GetMyValue()
是
MyStruct GetMyValue();
C#将如何处理ms变量的结构体返回?特别是如果它对于寄存器来说太大了怎么办?它是否会将其复制到堆中,然后再次复制回调用方法的位置并将其分配给ms?
编辑:
针对留在帖子中的评论:
在发布这篇文章之前,我已经阅读了一些有关C#结构体的教程,特别是this tutorial,其中使用的单词“
stack
”比我能数到的次数还要多。而this MSDN tutorial也谈到了堆栈,尽管它是来自2003年的,但我认为结构体从那时起并没有改变。我知道这可能与C#无关,实际上可能是JIT编译器本身或CLR或其他我不知道的东西的问题。这就是我的问题的目的,即了解C#的内部工作原理,即使这实际上与语言本身无关。
有C函数调用约定,最好支持我的帖子是this StackOverflow post。当我第一次在这里发布它时,我只是说出了我记得的,但由于SO答案说:
至于您的具体问题,它取决于ABI。有时,如果返回值大于4个字节但不大于8个字节,则可以将其拆分为EAX和EDX。但大多数情况下,调用函数将只分配一些内存(通常在堆栈上)并将指向该区域的指针传递给被调用函数。
我可能是错的,我说“可能”,因为答案说“通常”。
我想了解结构体如何处理的真正原因是,我有一个项目需要多次读取串行端口以轮询数据,这些数据将通过方法返回。
由于数据只是一些字节,所以我认为使用结构体而不是使用类来抽象串行端口传入的字节可以提高性能,但如果
return
将struct
作为堆分配传递,则我的性能期望可能是错误的。是的,我可以进行简单的测试并比较性能,我知道,但我想实际上学习它在幕后是如何完成的,而不仅仅是记忆我的模拟结果。我喜欢知道我使用的东西实际上是如何工作的,而不仅仅是学习如何使用它们。