我经常对此感到困惑。我一直被教导使用变量或常量来命名我经常使用的数字,但如果它降低了程序的效率,我是否仍然应该这样做?下面是一个示例:
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 应该是在该私有方法之外的某个地方声明的常量,在某个明显的地方,所有常量都声明在一起。或者,它可以是从配置中读取的变量。
当您在类库深处的私有方法中的某个位置为常量数命名时,它实际上不会改善您的代码。