使用变量与幻数的性能影响

时间:2013-10-18 18:58:11

标签: c# magic-numbers

我经常对此感到困惑。我一直被教导用经常使用变量或常量命名的数字,但如果它降低了程序的效率,我还应该这样做吗?下面是一个例子:

private int CenterText(Font font, PrintPageEventArgs e, string text)
    {
        int recieptCenter = 125;
        int stringLength = Convert.ToInt32(e.Graphics.MeasureString(text, font));
        return recieptCenter - stringLength / 2;
    }

上面的代码使用的是命名变量,但运行速度比这段代码慢:

private int CenterText(Font font, PrintPageEventArgs e, string text)
    {
        return 125 - Convert.ToInt32(e.Graphics.MeasureString(text, font) / 2);
    }

在这个例子中,执行时间的差异是最小的,但是在更大的代码块中呢?

3 个答案:

答案 0 :(得分:9)

使用变量和硬编码值之间的差异在最坏情况下可以忽略不计。编译器很好地处理这样的事情。如果您发现性能有所不同,我希望了解您收集这些指标的方法。 (您的测试本身可能是可疑的,很可能是不可重复的。)

在任何情况下,您都应该首先担心程序的正确性和可维护性。这意味着:

  • 小心地命名您的类,方法和变量
  • 分离关注
  • 避免使用魔法数字和字符串(这是什么125及其含义是什么?)
  • 避免录乱

此外,receiptCenter听起来不应该是一个常数。它可能不经常更改,但我建议您将它存储在您的应用程序之外的配置文件或数据库表等。如果该值需要更改,您必须重新编译并推动整个事情。另外,如果在receiptCenter的价值不同的其他地方发布您的软件呢?您只想更改配置设置,而不是仅为该实例构建不同版本的应用程序。

优化是您最不担心的事情,除非您首先要担心这是建筑师/专家级别的考虑因素。

答案 1 :(得分:9)

当他们说“使用常数”时,他们的字面意思是“使用常量”;它们并不意味着“使用永不改变的变量”。

这相当于您的代码:

const int recieptCenter = 125;
int stringLength = Convert.ToInt32(e.Graphics.MeasureString(text, font));
return recieptCenter - stringLength / 2;

使用const关键字,编译器知道125永远不会改变,并且能够应用它将应用于表示为文字的常量的优化。

命名您的“神奇数字”有一个巨大的优势:在您离开公司后维护代码的人会知道125的含义是什么。当你几年后回来重新审视这段代码时,它也会对你有所帮助。

答案 2 :(得分:-1)

receiptCenter应该是在私有方法之外的某个地方声明的常量,在一些显而易见的地方,所有常量都在一起声明。或者,它可以是从配置读取的变量。

当你在类库深处的私有方法中给某个常量数字命名时,它确实没有改进你的代码。