【问题标题】:Boxing Memory concerns [closed]拳击记忆问题[关闭]
【发布时间】:2011-05-10 13:13:02
【问题描述】:
private double _value;


public object Value
{
    get
   {
         return _value;
   }

}

我正在进行代码审查,并在我们的代码库中注意到了这一点。这不是一个错字,但我担心的是拳击。这是在调用 getter 时涉及的,并且鉴于此代码属于一种类型,它会生成数百次并且经常调用 getter,我可以看到内存问题。

我对记忆的担忧是否正确?我的意思是我们会因为拳击而加倍吗?

【问题讨论】:

    标签: c# .net properties boxing


    【解决方案1】:

    是的,您显示的代码 sn-p 确实会导致装箱。您正在强制运行时将double 转换为object。如果您想向自己或同事证明这一点,请查看编译后的 IL 以了解 boxunbox 说明。

    但是,尽管您尽可能避免拳击是正确的,但实际的性能损失并不总是像炒作所表明的那样严重。在对代码库进行重大更改之前,请花一些时间进行分析,以确保您花费时间处理的代码确实是性能瓶颈。

    鉴于上面的具体示例,为什么首先需要返回类型 object 并不是特别清楚。由于您只是返回私有字段的值,因此您可以简单地将属性更改为返回类型 double

    或者,您可以将属性转换为通用方法。 (属性不能是泛型的,但方法可以,如果你在 getter 中进行计算密集型工作,它可能无论如何应该是一种方法。)泛型缓解了装箱问题,但仍然允许你在很大程度上返回类型的灵活性(类似于返回类型object)。

    【讨论】:

      【解决方案2】:

      是的,每次调用 getter 时都会创建一个新对象。

      是的,这需要记忆。

      这有问题吗?只有你能说。这取决于它发生的频率,以及是否有更好的选择。是否有某些原因需要 声明返回object 而不是double?无论如何都会将其分配给object 类型变量(在这种情况下,无论如何都会发生装箱)?

      拳击是那些真实的性能问题之一,但often exaggerated。如果它在您的应用程序中每秒发生数十万次,那可能很重要。如果每小时发生数百次,您应该更关心 API 是否合适,而不是性能成本。

      【讨论】:

      • 它是一个实时应用程序,所以它更像是每秒一百次
      • @Andy:每秒仅 数百次 次可能并不重要。但是测试一下!
      【解决方案3】:

      您对此有点担心是对的,如果不出意外,这绝对是一种反模式。

      然而,与其在这里解释,这篇文章真的很不错:

      http://www.codeguru.com/csharp/csharp/cs_syntax/article.php/c5883

      希望这会有所帮助!

      【讨论】:

        【解决方案4】:

        实际开销因平台而异。 Double 的大小在所有平台上都是固定的,但是当值被装箱时,它将引用运行时类型对象。参考的大小是特定于平台的。因此,对象总共将是 32 位上的 16 个字节和 64 位上的 24 个字节。每次调用都会创建一个新对象。如果这将是一个问题,我不能说,但我怀疑它。如果有疑问,请对其进行分析。

        【讨论】:

        • 我调用 Value 它将返回一个装箱值(指针)。如果我再次调用 Value,我会得到一个指向同一个对象或新对象和新指针的新指针
        • @Andy:每次调用都会得到一个新对象。
        猜你喜欢
        • 1970-01-01
        • 2021-08-05
        • 1970-01-01
        • 1970-01-01
        • 2010-09-15
        • 1970-01-01
        • 1970-01-01
        • 2023-02-04
        相关资源
        最近更新 更多