对于我的工作,我必须开发一个小型Java应用程序来解析非常大的XML文件(~300k行)以选择非常具体的数据(使用Pattern
),所以我试图对它进行一些优化。我想知道这两个片段之间有什么好处:
if(boolean_condition && matcher.find(string))
{
...
}
或
if(boolean_condition)
{
if(matcher.find(string))
{
...
}
}
更精确:
boolean_condition
是使用外部函数boolean
boolean
设置为false
,我无需测试匹配的正则表达式感谢您的帮助
答案 0 :(得分:51)
我遵循的一条黄金法则是尽可能多地避免嵌套。但是,如果以使我的单一if条件过于复杂为代价,我不介意将其嵌套。
此外,您正在使用短路&&
运算符。因此,如果布尔值为false,它甚至不会尝试匹配!
所以,
if(boolean_condition && matcher.find(string))
{
...
}
是要走的路!
答案 1 :(得分:18)
以下两种方法:
public void oneIf(boolean a, boolean b)
{
if (a && b)
{
}
}
public void twoIfs(boolean a, boolean b)
{
if (a)
{
if (b)
{
}
}
}
为方法体生成完全相同的字节代码,因此不存在任何性能差异,这意味着它纯粹是一种风格问题(我个人更喜欢第一种风格)。
答案 2 :(得分:4)
两种方式都可以,如果第一个条件为假,则不会测试第二个条件。
使用使代码更易读和易懂的代码。对于两个条件,第一种方式更具逻辑性和可读性。如果5个或6个条件与&&
,||
和!
相关联,则可能不再是这种情况。
答案 3 :(得分:2)
Java对这些布尔运算符使用短路,因此两种变体在功能上都是相同的。因此,如果boolean_condition
为false,则不会继续匹配
最终,它归结为你发现更容易阅读和调试,但如果你最后得到大量的括号,深度嵌套会变得笨重
如果条件变得更长,可以提高可读性的一种方法是简单地将其拆分为多行:
if(boolean_condition &&
matcher.find(string))
{
...
}
此时唯一的选择是是否将&&&和||在前一行的末尾,或当前的开始。
答案 4 :(得分:1)
第一个。我试图避免如果这样嵌套,我认为这是糟糕的风格/丑陋的代码和&&将短路并仅使用matcher.find()进行测试,如果布尔值为真。
答案 5 :(得分:1)
就性能而言,它们是相同的。
这段代码中几乎可以肯定的是matcher.find(string)
,因为它是一个函数调用。
答案 6 :(得分:1)
我倾向于看到太多&&和||汇总成逻辑汤,往往是微妙的错误的来源。
太容易添加另一个&&或||你认为是正确的选择并打破现有的逻辑。
由于这一般作为一般规则,我尽量不使用它们中的任何一个来避免在需求变化时添加更多的诱惑。
答案 7 :(得分:1)
如果你愿意遵守Sonar rule squid:S1066,你应该崩溃if语句以避免警告,因为它声明:
可折叠的“if”语句应该合并
答案 8 :(得分:0)
我建议将您的表达式提取为一个有意义的语义变量,然后将其传递给您的评估。代替:
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) { ... }