4

我对许多问题的反应感到有些震惊,这些问题指出开发人员更关心生成的编译字节而不是代码的含义。我倾向于对后缀/前缀增量进行挑剔,因为我倾向于对具有两个值的枚举类型使用布尔值以及正确的函数命名以及...

所以这个问题更像是一个反省的民意调查:什么时候允许一个人忽视一个人所写内容的语义?边界线在哪里?

  • 运算符++(后缀/前缀)
  • string.empty() 与 string == ""
  • vector.empty() 与 vector.size() == 0
  • enumerate { on, off} vs. boolean on=true; 关闭=假
  • ...

命名它。

编辑 -

我并不是要质疑(微)优化的必要性。相反,我想就你应该如何意识到你在写什么,以及“但它编译成一个 dword,无论如何,我为什么要把它变成一个枚举”这样的陈述提出意见。(这是一个极端的情况......)。

4

10 回答 10

9

定义“好”。如果它在初始交付日期有效,是否可以,但每次您需要进行更改时,都需要额外的三周时间才能弄清楚旧代码?

这就是你的答案:只要你能理解代码并且它不会损害你维护它的能力。

于 2009-01-27T18:47:47.863 回答
4

在我的职业生涯中,我编写了很多代码。当然这里没有那么多人,但仍然有很多代码。在那段时间里,我学到了一件事,一次又一次地被证明是正确的:当你马虎,当你忽视细节时,缺陷就会蔓延。

缺陷需要花费时间和金钱来修复。您可以花时间在前面干净清晰地编写代码,这样做很便宜,或者您可以在以后花费大量时间和金钱来追查您可能不太记得的代码缺陷,因为您匆忙将它拍打在一起,或者因为它不符合编码标准。最终结果是,你在浪费时间和金钱。此外,您正在浪费时间和金钱,因为您可以通过一点前期投资来避免浪费。

我从不后悔对自己编写代码的方式一丝不苟。它再也没有回来困扰我。邋遢总是困扰着我。

于 2009-01-28T00:03:26.057 回答
3

当你开始担心对底线没有影响的深奥的东西时,我认为这太过分了。讨论是否使用三元运算符或写明确的 if 语句适合那些无事可做,只能坐下来,站起来,啜饮啤酒/葡萄酒/苏打水并讨论“重大后果”问题的日子:)

但是为布尔创建一个枚举是完全错误的。

于 2009-01-27T18:50:35.877 回答
3

取决于你的成本函数

这里有几个人们喜欢争论并且经常混为一谈的维度。真的,答案是视情况而定。你真正看重的是什么?

  • 字符数
  • 创建的操作数
  • 运行
  • 可移植性
  • 可维护性
  • 明晰
  • 聪明
  • 稳定性(没有错误?)
  • 可扩展性

我总是首先瞄准更高阶的东西,比如清晰度。在人类周期中,清晰度的丧失是有代价的,而人类周期总是存在不足的。人们很少关心原始时钟时间,而那些说他们关心的人几乎总是过早地优化。

如果它对你有任何帮助,我喜欢认为我们正在通过提升堆栈取得进展,更多地关心语义和工作完成,而不是成为位和数字的奴隶。然而,这并不是忘记基本原理并记住某些语义位是如何实现的借口。在那些速度开始变得重要而惯例被排除在外的难得机会中,您不想陷入困境。

于 2009-01-27T18:50:55.313 回答
3

“什么时候可以无视所写内容的语义?边界在哪里?”

我认为一个合理的问题是:“什么时候应该忽略所写内容的语义?”

由于我将编程视为一种人类活动,我想说唯一一次应该忽略语句的语义是系统本身强迫你 - 当一些难以理解的语句是做某事的唯一方法时。这样的陈述很好记录。

于 2009-01-27T18:53:15.620 回答
2

边界是当您处理一次写入、永不读取的代码时。只有这样,你在做什么(在那种情况下)最终才无关紧要,因为你永远不会再使用它。不幸的是,这并没有解决你不想重复的练习的间接反馈。

于 2009-01-27T18:50:31.290 回答
1

边界线是副作用。

如果一个封装的函数可以完成您想要的所有操作,并且没有 0 个意外副作用,并且代码是可读的,那么这就是最重要的。如果您对外部用户来说是可预测的,并且任何“奇怪”的功能都保留在内部,那就很重要了。

如果您添加优化,它会略有变化,但由于您永远不应该过早优化,这就是它结束的地方。

于 2009-01-27T18:47:29.253 回答
1

我认为现在大多数人都同意,假设它工作正常,可读性是最重要的考虑因素。当然也有例外——有些应用程序必须尽可能快地运行,有些应用程序永远不允许崩溃,但一般来说它是可读性的。

于 2009-01-27T18:49:20.137 回答
1

微优化在 99% 的情况下都是毫无意义的。例如,如果您的编译器无论如何都将所有“”实习生到单个实例,那么您不会通过使用 String.Empty 以任何方式提高性能。没有任何可测量的效果通常也是您所希望的最好的,我已经看到“优化”会降低性能,因为编译器做得更好,而优化会干扰它。

大多数代码不需要优化。识别需要在哪里发生,只能在代码运行后通过诊断来完成,即使这样,大部分时间也是通过算法优化来完成的,而不是微优化。

于 2009-01-27T18:57:44.880 回答
1

观察您提供的示例-以下内容:

operator++(后缀/前缀)

string.empty()对比string == ""

这似乎不是很好的例子,因为它们比较了functionality. 因此,最好不要忽视它们的语义区别。

相比之下,以下示例:

vector.empty()对比vector.size() == 0

enumerate { on, off} 与boolean on=true;off=false

完全合理。

vector.empty()如果它的使用上下文仅用于确定向量是否为空,则更可取。冒着听起来居高临下的风险(我打算这样做):这归结为常识。如果您只想知道向量是否为空,为什么还要询问向量的大小?这就像问某人钱包里有多少钱,而您只是想知道他们是否有足够的现金来喝可乐。

至于enumerate { on, off} vs. boolean on=true; off=false,问问自己这个问题:将来您向枚举添加另一个值的可能性有多大?人们可能想要enumerate{ on, off, indeterminate}` (或一些变体)似乎是合理的,所以答案可能是肯定的。否则,一个简单的布尔值就足够了。

这使我想到了您问题的症结所在:似乎是否有某种确定性/算法方法可以在诸如此类的问题或它们的相关性上决定一种或另一种方式?我的回答是,直到图灵机能够通过图灵测试的那一天,我会说不。这就是为什么需要人类来设计软件的原因。

于 2009-01-27T23:23:26.450 回答