为了可读性与否,使用布尔变量来替换if条件更好吗



我正在攻读信息技术学士学位的第二年。去年,在我的一门课程中,他们教我写干净的代码,这样其他程序员就可以更轻松地处理你的代码。我从pluralsight(我的学校使用的付费学习网站)上的一段视频("干净代码")中学到了很多关于编写干净代码的知识。其中有一个例子,将if条件分配给布尔变量,并使用它们来增强可读性。在我今天的课程中,我的老师告诉我,这是一个非常糟糕的代码,因为它会因为执行的测试增加而降低性能(在更大的程序中)。我现在想知道是应该继续使用布尔变量来提高可读性,还是不使用它们来提高性能。我将在一个例子中说明(我在这个例子中使用python代码):

  • 示例布尔变量

假设我们需要检查某人饮酒是否合法,我们知道这些人的年龄,我们知道合法饮酒年龄是21岁。

is_old_enough = persons_age >= legal_drinking_age
if is_old_enough:
do something

我的老师今天告诉我,这对表现非常不利,因为要进行两项测试,第一项测试是persons_age>=legal_dinking_age,第二项测试是如果再进行一项测试,则该人是否为old_enough。我的老师告诉我,我应该把条件放在if中,但在视频中,他们说代码应该像自然语言一样阅读,以便其他程序员清楚地理解。我现在想知道哪一种是更好的编码实践。

  • if中的示例条件:

    if persons_age >= legal_drinking_age:
    do something
    

在本例中,仅测试一项测试persons_age>=legal_dinking_age。根据我老师的说法,这是更好的代码。

提前谢谢!

忠实的

乔纳斯

我现在想知道哪种编码方法更好。

真正安全的答案是:取决于。。

我不想用这个答案,但除非你有坚定的怀疑,否则你不会问。(:

IMHO:

如果代码将用于长期使用,而可维护性很重要,则首选可读性清晰的代码。

如果程序速度性能至关重要,那么任何使用较少资源的代码操作(较小的dataSize/dataType/实现相同任务所需的较少循环/优化的任务排序/最大化每个时钟周期的cpu任务/减少数据重新加载周期)都会更好。(示例关键字:空格表示时间代码)

如果程序最大限度地减少内存使用是至关重要的,那么任何使用较少存储和内存资源来完成其操作的代码操作(对于同一任务可能需要更多的cpu周期/循环)都会更好。(例如:数据存储/RAM有限的小型设备)

如果你正在竞争,那么你可以尽可能短地编写代码(即使以后可能需要更长的cpu时间)。示例:黑客马拉松

如果你正在编程教一组学生/朋友一些东西。。那么可读代码+大量注释绝对是首选。

如果是我……我会尽可能地使用最接近汇编语言的语言(尽可能多地控制位操作)进行后端开发。以及任何最接近mathematica的代码(更少的代码,最大的输出,不在乎需要多少cpu/内存资源),用于前端开发。(:

所以。。如果是你。。你可能有自己的要求/偏好。。从用户/外部人员/客户的角度来看。。这只是一个工作程序。你对好程序的定义可能会与其他人不同。。但这不应该阻止我们在编码风格/方法上保持灵活性。

愉快的探索。希望能有所帮助。。以任何可能的方式。

性能

性能是这个问题最不令人感兴趣的问题之一,我认为这是一个在图像处理和光线追踪等性能关键领域工作的人,他相信有效的微观优化(但我对有效微优化的想法是改善内存访问模式和内存布局以提高缓存效率,而不是因为担心编译器或解释器可能会分配额外的寄存器和/或使用额外的指令而消除临时变量)。

它不那么有趣的原因是,正如评论中所指出的,任何一个像样的优化编译器都会在完成对中间表示的优化并生成指令选择/寄存器分配的最终结果以产生最终输出(机器代码)时,将您编写的这两个编译器视为等效编译器。如果你没有使用一个像样的优化编译器,那么这种微观效率可能是你最不应该担心的。

可变范围

撇开性能不谈,我对这个约定唯一关心的是,对于那些没有命名常量概念来将其与变量区分开来的语言,我认为它通常是一个很好的自由应用约定。

在这些情况下,向丰富的函数引入的变量越多,随着范围相对较广的变量数量的增加,它的智力开销就越大,在极端情况下,这可能会转化为维护和调试的实际负担。如果你想象这样的情况:

some_variable = ...
...
some_other_variable = ...
...
yet_another_variable = ...
(300 lines more code to the function)

在某个函数中,当你试图调试它时,这些变量与函数的巨大大小相结合,开始增加找出问题所在的难度。这是我在调试跨越数百万行代码的代码库时遇到的一个实际问题,这些代码库由各种各样的人(包括那些不再在团队中的人)编写,在调试器中查看本地监视窗口,并在某个看起来做得不正确的可怕函数(或它调用的某个函数)中看到两页的变量,这就不那么有趣了。

但这只是一个问题,当它与有问题的编程实践相结合时,比如编写跨越数百或数千行代码的函数。在这些情况下,它通常会改进一切,只需专注于制作大小合理的函数,这些函数可以执行一个清晰的逻辑运算,并且不会有多个副作用(如果函数可以编程为纯函数,则理想情况下不会有副作用)。如果你合理地设计你的函数,那么我根本不会担心这一点,我更喜欢那些可读性强、一眼就能理解的东西,甚至可能是最可写、最"灵活"的东西(如果你预计未来需要,可以更容易地更改函数)。

变量作用域的语用学观点

因此,我认为,只要理解缩小变量范围的必要性,就可以在一定程度上理解许多编程概念。人们说要避免像瘟疫这样的全球性变量。我们可以讨论共享状态如何干扰多线程,以及它如何使程序难以更改和调试的问题,但您可以通过缩小变量范围来理解许多问题。如果你有一个跨越十万行代码的代码库,那么一个全局变量的访问和修改范围将达到十万行代码,粗略地说,会有十万种错误。

同时,这种务实的观点会发现,让一个只跨越100行代码、未来不需要扩展的一次性程序避免瘟疫等全局变量是毫无意义的,因为可以说,这里的全局只有100行的范围。同时,即使是在所有上下文中都避免了瘟疫之类的问题的人,也可能会编写一个包含成员变量(包括一些为了"方便"而多余的变量)的类,其实现跨越8000行代码,此时这些变量的范围甚至比前一个示例中的全局变量要宽得多,这种实现可以驱使人们设计更小的类和/或减少多余的成员变量的数量,以作为类的状态管理的一部分(这也可以转化为简化的多线程和在一些非平凡的代码库中避免全局变量的所有类似类型的好处)。

最后,它往往会诱使您编写更小的函数,因为一些函数顶部的变量跨越500行代码,其范围也相当大。所以,不管怎样,当你这样做的时候,我唯一关心的是不要让那些临时的局部变量的范围变得太宽。如果他们这样做了,那么一般的答案不一定是避免这些变量,而是缩小它们的范围。

最新更新