拳击记忆问题

时间:2011-05-10 13:13:03

标签: c# .net properties boxing

private double _value;


public object Value
{
    get
   {
         return _value;
   }

}

大家好,只是在我们的代码库中进行代码审查并注意到这一点。它不是一个拼写错误,但我关注的是调用getter时涉及的拳击,并且假设这个代码是一个生成数百次的类型,并且频繁调用getter我可以看到内存问题。

我的担忧是否与记忆有关?我的意思是,由于拳击,我们加倍了吗?

4 个答案:

答案 0 :(得分:6)

是的,您展示的代码段确实会导致拳击。您迫使运行时将double转换为object。如果您想向自己或同事证明,请查看已编译的IL以获取告诉boxunbox说明。

然而,尽管你在可能的情况下正确地避免拳击是正确的,但实际的性能损失并不总是像宣传那样重要。在对代码库进行重大更改之前,请花一些时间进行性能分析,以确保您花费时间的代码确实是性能瓶颈。

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

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

答案 1 :(得分:1)

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

是的,这将占用记忆。

虽然这是一个问题吗?只有你可以说。这取决于它发生的频率,以及是否有更好的选择。有没有理由将需要声明为返回object而不是double?它是否会被分配到object类型变量(在这种情况下拳击会发生,无论如何)?

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

你是对此有点担心,如果没有别的,那肯定是反模式。

然而,不过在这里解释一下,这篇文章是一篇非常好的读物:

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

希望这有帮助!