C#中的'ref'关键字及其性能表现

13

如果您有一个需要传递到多个方法(大约10个),最终传递到一个事件的Bitmap对象,在使用后将被销毁,那么通过引用而不是值将其传递给这些方法中的每一个是否有性能上的好处?

按值传递,对象会被复制;按引用传递,对象不会被复制。

(在这种情况下,性能至关重要。应用程序需要尽可能快地运行。)


vb.net: byval和byref哪个更快 - nawfal
无论如何都没有办法通过值传递位图。 - IS4
4个回答

34

位图是引用类型。按值传递引用类型不会复制对象,只会复制对象的引用。将位图通过引用传递而不是按值传递不会带来性能优势。


18

感谢您提供的文章链接,对我非常有帮助。非常感激,伙计。 - David Anderson
1
不错的文章推荐。它是一篇很棒的阅读材料,可以彻底理解值类型、引用类型和按值/按引用传递参数。 - Jaanus Varus

10
你到底是使用哪种类型来保存位图的?例如,System.Drawing.Bitmap 是一个引用类型/类。当你将一个引用传递给一个方法时(作为参数),该引用按值传递。(只复制引用...而不是对象)因此,在32位机器上分配四个字节来保存该副本。
使用 ref 关键字对性能没有太大影响,除了传递相同的引用(不会复制引用)。它具有以下优点:
  • 仅澄清了该方法的意图,即获取参数 可能会被修改,并且调用者在执行后可能获得一个修改后的值。
  • 并且在将变量作为 ref 参数传递给调用的函数之前,必须由被调用方初始化

感谢您提供的额外细节,伙计! - David Anderson
1
使用ref关键字...仅清除意图是不正确的。通过引用传递(object*)的引用可以被调用者重新分配;影响调用者引用指向的对象。通过值传递引用(object)传递引用的副本,将调用者引用与调用内部的更改隔离开来。这篇文章http://preview.tinyurl.com/oda4jz在C#中有一个例子。 - corlettk
正确。因此,采用 ref 参数的方法强制调用者在参数前显式写出 ref - 以确保调用者理解并同意语义。它澄清了调用者传递参数的意图,即调用者传递参数时完全知道该参数在方法调用后可能具有不同的值/状态。 - Gishu

9
'ref' 不会将对象本身传递到函数中,而是传递对存储在/在其中的变量的引用。
如果对象是一个类或接口,那么每当您在函数中访问该变量时,它必须对其进行取消引用,然后访问该变量。如果没有使用 'ref' 关键字传递,则不必执行取消引用步骤(因此速度会略有提高)。
如果对象是结构体(或枚举或其他基本类型),则 'ref' 关键字会传递到存储结构体的变量的引用,这仍然会导致轻微的速度减慢,每次使用它时都要取消引用。但是,如果您不指定它,则程序必须为结构的新实例分配内存,然后复制它。在大多数情况下,通过 ref 关键字传递结构体通常更快,但如果它是非常小的结构体,或者如果它被取消引用了很多次(我是说很多次),则可能不是这种情况。
因此,如果要传递结构体,则通常要使用 ref,否则不会有太大区别(取消引用阶段的开销微不足道)。
哦,实际上回答问题,Bitmap 是一个类,所以 'ref' 关键字与非 'ref' 参数相比不会带来速度差异。

指出通过引用传递结构体的好处,并更详细地解释取消引用的性能影响。 - Didaxis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接