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



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

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);
    }

在此示例中,执行时间的差异很小,但是在较大的代码块中呢?

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

这等效于您的代码:

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

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

命名你的"幻数"有一个巨大的优势:在你离开公司后维护你的代码的人会知道125的含义。当您几年后回来重新访问此代码时,它也会对您有所帮助。

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

在任何情况下,您都应该首先考虑使程序正确且可维护。这意味着:

  • 仔细命名类、方法和变量
  • 分离关注点
  • 避免幻数和字符串(到底是什么125,这意味着什么?
  • 避免编码
  • 等。

此外,接收中心听起来甚至不应该是一个常量。它可能很少更改,但我建议您将其存储在应用程序外部的配置文件或数据库表等中。如果该值需要更改,则必须重新编译并将整个值推送到prod。另外,在收据中心价值不同的其他地方发布软件怎么样?您只想更改配置设置,而不是仅为该实例构建不同版本的应用。

优化是你最不担心的事情,除非它是你必须担心的第一件事,这是架构师/专家级的考虑因素。

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

当您在类库深处的私有方法中的某个位置为常量数命名时,它实际上不会改善您的代码。

最新更新