哪个更好:多个“if”语句或一个带有多个条件的“if”?
Posted
技术标签:
【中文标题】哪个更好:多个“if”语句或一个带有多个条件的“if”?【英文标题】:What is better: multiple "if" statements or one "if" with multiple conditions? 【发布时间】:2011-07-12 17:01:32 【问题描述】:对于我的工作,我必须开发一个小型 Java 应用程序来解析非常大的 XML 文件(约 30 万行)以选择非常具体的数据(使用 Pattern
),所以我正在尝试对其进行一些优化。我想知道这 2 个 sn-ps 之间哪个更好:
if (boolean_condition && matcher.find(string))
...
或
if (boolean_condition)
if (matcher.find(string))
...
其他细节:
这些 if 语句在循环内的每次迭代中执行(约 20k 次迭代)boolean_condition
是使用外部函数在每次迭代中计算得到的 boolean
如果boolean
设置为false
,我不需要测试正则表达式是否匹配
感谢您的帮助。
【问题讨论】:
没有简单的答案。查看this SO discussion关于同一主题的信息。 没有任何性能差异。这纯粹是一个风格问题,这使它成为一个见仁见智的问题。 【参考方案1】:我遵循的一条黄金法则是尽可能“避免嵌套”。但如果它的代价是使我的单个 if 条件过于复杂,我不介意将它嵌套出来。
除了您使用的是短路&&
运算符。所以如果布尔值是假的,它甚至不会尝试匹配!
所以,
if (boolean_condition && matcher.find(string))
...
是要走的路!
【讨论】:
谢谢!我不确定运算符是否设置为 false,匹配是否会执行。 考虑if(x != null && x.isY())
;如果 &&
没有 使评估短路,那会在 x == null 的瞬间炸毁你的脸。
确实如此!但我必须确定,所以我问
+adarshr 好吧,即使在嵌套的 if 中,它也会短路,因为如果外部 if 评估为 false,那么它不会费心检查内部 if,如果第一个评估为false 会短路
@user 你不会在评估之前检查 null 吗?常识说是? ArgumentNullException 也许?【参考方案2】:
第一个。如果像这样嵌套,我会尽量避免,我认为这是糟糕的样式/丑陋的代码,&& 会短路,并且只有在布尔值为真时才使用 matcher.find() 进行测试。
【讨论】:
【参考方案3】:两种方式都可以,如果第一个条件为假,则不会测试第二个条件。
使用使代码更具可读性和可理解性的代码。仅针对两个条件,第一种方式更具逻辑性和可读性。与&&
、||
和!
相关联的 5 或 6 个条件可能不再是这种情况。
【讨论】:
【参考方案4】:Java 对这些布尔运算符使用短路,因此这两种变体在功能上是相同的。因此,如果boolean_condition
为假,则不会继续匹配
归根结底,你会发现它更易于阅读和调试,但如果你最终得到大量大括号,深度嵌套可能会变得笨拙
如果条件变长,提高可读性的一种方法是简单地将其拆分为多行:
if(boolean_condition &&
matcher.find(string))
...
此时唯一的选择是是否放 && 和 ||在上一行的末尾,或当前行的开头。
【讨论】:
【参考方案5】:以下两种方法:
public void oneIf(boolean a, boolean b)
if (a && b)
public void twoIfs(boolean a, boolean b)
if (a)
if (b)
为方法主体生成完全相同的字节码,因此不会有任何性能差异,这意味着它纯粹是您使用的风格问题(我个人更喜欢第一种风格)。
【讨论】:
我不会怀疑public void noIfs(boolean a, boolean b)
方法是否也产生了相同的字节码 ;-)
@Axel 不,它没有(我刚刚检查过!)这并不奇怪,Java 编译器几乎没有优化,让 JVM 在运行时完成。
我认为解析器在第二个构造中还有更多工作要做,因为它必须确定下一条语句是'if'还是其他东西。另一方面,在第一个构造中,它只会解析条件,并且知道跟随是条件的一部分。【参考方案6】:
在性能方面,它们是相同的。
但即使他们不是几乎可以肯定,这段代码中占主导地位的是matcher.find(string)
,因为它是一个函数调用。
【讨论】:
【参考方案7】:我倾向于看到太多的 && 和 ||串在一起形成逻辑汤,通常是微妙错误的来源。
添加另一个 && 或 || 太容易了到你认为正确的地方,打破现有的逻辑。
因此,作为一般规则,我尽量不使用其中任何一个,以避免随着需求的变化而增加更多内容的诱惑。
【讨论】:
【参考方案8】:如果您希望遵守Sonar rule squid:S1066,您应该折叠 if 语句以避免警告,因为它声明:
应合并可折叠的“if”语句
【讨论】:
【参考方案9】:我建议将您的表达式提取为具有语义意义的变量,然后将其传递给您的评估。而不是:
if (boolean_condition && matcher.find(string)) ...
将表达式分配给变量,然后计算变量:
const hasItem = boolean_condition && matcher.find(string)
if (hasItem) ...
使用这种方法,即使是最复杂的评估也可以保持可读性:
const hasItem = boolean_condition && matcher.find(string)
const hasOtherThing = boolean_condition || boolean_condition
const isBeforeToday = new Date(string) < new Date()
if (hasItem && hasOtherThing && isBeforeToday) ...
【讨论】:
【参考方案10】:由于“&&”,大多数人更喜欢使用下面的那个。
if (boolean_condition && matcher.find(string))
...
我们通常将这些称为“短路(或最低评估)”。这意味着只有当第一个参数没有足够的信息来确定表达式的值时,才会评估第二个参数(这里是“matcher.find(string)”)。例如,如果“boolean_condition”是false,那么整体条件一定是false(因为这里是逻辑AND 运算符)。然后编译器不会检查第二个参数,这将导致减少代码的运行时间。
【讨论】:
这不是已经包含在现有答案中了吗? (更重要的是——这可能在 2011 年被认为是热门话题,但在 2021 年,这个问题显然过于基于观点而不能成为话题,这意味着How to Answer 适用)。以上是关于哪个更好:多个“if”语句或一个带有多个条件的“if”?的主要内容,如果未能解决你的问题,请参考以下文章