【问题标题】:C# 'ref' keyword, performanceC# 'ref' 关键字,性能
【发布时间】:2010-10-28 09:43:33
【问题描述】:

如果您有一个 Bitmap 对象需要传递给许多方法(大约 10 个),最后传递给一个事件,在使用后最终将其处理掉,那么将它传递给(在性能方面)是否有益这些方法中的每一个都是引用而不是值?

通过值传递,对象被复制,通过引用传递它不是。

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

【问题讨论】:

标签: c# performance ref


【解决方案1】:

由于 Bitmap 是一种引用类型,因此在这种情况下性能没有实际差异,因为它已经通过引用传递给方法。

我建议Jon Skeet's article on the subject 详细解释“按引用”和“按值”在 C# 中的工作原理。

【讨论】:

  • 感谢文章的链接,真的帮助了我。欣赏它芽
  • 不错的文章推荐。深入理解值/引用类型和按值/引用传递参数是一本很好的读物。
【解决方案2】:

'ref' 不会将对象本身传递给函数,而是传递对存储在/at 中的变量的引用。

如果对象是类或接口,那么每当您在函数中访问该变量时,它必须取消引用它,然后访问该变量。如果它是在没有 'ref' 关键字的情况下传入的,那么它就不必执行取消引用步骤(因此它会稍微快一些)。

如果对象是结构体(或枚举或其他基本类型),'ref' 关键字将引用传递给存储结构体的变量,这仍然会导致在使用它时解引用的轻微速度命中,但如果你不指定它,那么程序必须为结构的新实例分配内存,然后复制它。在大多数情况下,通过 ref 关键字传递结构会更快,但如果它是一个非常小的结构,或者它被取消引用很多(我的意思是很多),情况可能并非如此。

因此,如果您要传递一个结构,那么 ref 通常是要走的路,否则不会有太大的区别(取消引用阶段的开销是微不足道的)。

哦,实际上要回答这个问题,位图是一个类,因此“ref”关键字不会真正对非“ref”参数产生速度差异。

【讨论】:

  • +1 指出了通过引用传递结构的好处,并更全面地解释了取消引用的性能影响。
【解决方案3】:

您使用哪种类型来保存位图?例如,System.Drawing.Bitmap 是引用类型/类。当您传递对方法的引用(作为参数)时,引用是按值传递的。 (制作了引用的副本...而不是对象)因此将在 32 位机器上分配四个字节来保存副本。

使用 ref 关键字对性能没有太大影响,只是传递了相同的引用(不复制引用)。它有以下好处

  • 仅清除采用参数的方法可能修改它的意图,调用者可能会在执行后获得修改后的值。
  • 并且变量必须由被调用者初始化,然后才能作为参数传递给采用 ref 参数的被调用函数。

【讨论】:

  • 感谢您提供额外的详细信息!
  • “使用 ref 关键字 ... 只会清除意图”。嗯,我不认为这是真的。调用者可以重新签名通过引用传递的引用(对象**);影响调用者引用的对象。按值传递引用 (object*) 传递引用的副本,从而将调用者引用与被调用者中的更改隔离开来。这篇文章preview.tinyurl.com/oda4jz有一个C#的例子。
  • 正确。因此,采用 ref 参数的方法会强制调用者在参数之前显式写入 ref - 以确保调用者理解并同意语义。它阐明了调用者传递参数的意图,完全意识到参数在方法调用后可能具有不同的值/状态。
【解决方案4】:

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

【讨论】:

    猜你喜欢
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 2020-10-02
    • 1970-01-01
    • 2011-11-24
    • 2010-12-02
    相关资源
    最近更新 更多