C#函数正常返回值VS out或ref参数

时间:2010-05-16 07:22:34

标签: c# arguments return

我在C#中有一个方法需要返回一个非常大的数组(或任何其他大型数据结构)。

使用ref或out参数而不是标准返回值是否有性能提升?

即。使用

是否有任何表现或其他收获
void function(sometype input, ref largearray)

largearray function(sometype input)

4 个答案:

答案 0 :(得分:5)

32位x86处理器上用于传递各种类型参数的堆栈空间量:

  • 字节:4个字节
  • bool:4个字节
  • enum:4个字节
  • char:4个字节
  • 短:4个字节
  • int:4个字节
  • long:8个字节
  • float:4个字节
  • double:8个字节
  • 十进制:16字节
  • struct:结构的运行时大小

  • string:4 bytes
  • 数组:4个字节
  • object:4个字节
  • interface:4 bytes
  • 指针:4个字节
  • 类实例:4个字节

该行下面的是引用类型,它们的大小将在64位处理器上加倍。

对于静态方法调用,最多4个字节的前2个参数将通过CPU寄存器传递,而不是堆栈。对于实例方法调用,只有一个参数将通过寄存器传递。其余的都在堆栈上传递。 64位处理器支持通过寄存器传递4个参数。

从列表中可以清楚地看出,你应该考虑通过ref传递参数的唯一时间是结构。对此的正常指导是在结构大于16个字节时这样做。猜测结构的运行时大小并不总是容易的,通常最多4个字段是准确的。如果这些字段是double,long或decimal,则减少。然后,本指南通常建议将您的结构转换为类,正是出于这个原因。

另请注意, no savings 故意将参数作为字节或短路传递,int是32位处理器满意的类型。与当前可用的64位处理器相同。


方法返回值,问题的真实主题几乎总是在CPU寄存器中返回。大多数类型适合放在eax或edx:eax寄存器中,FPU寄存器用于浮点值。唯一的例外是大结构和十进制,它们太大而不适合寄存器。通过在堆栈上为返回值保留空间并将4字节指针传递给该空间作为方法的参数来调用它们。

答案 1 :(得分:1)

out参数返回对类型实例的引用,在发送到方法之前不需要对其进行初始化。

ref参数返回对类型实例的引用, 必须 才能在发送到方法之前进行初始化。

这是关于调用语义,而不是性能。

答案 2 :(得分:1)

没有,只需返回数组

答案 3 :(得分:1)

之间没有区别
void function(sometype input, out largearray output ) 

largearray function(sometype input)

但是,如果你这样做

largearray function( sometype input, ref largearray output )

并且您需要调用者预先分配大数组,这当然会更快,但只有重复调用该方法并保持在调用之间分配大数组才会有效。