2017-03-09 112 views
1

SonarQube认为下面的代码违反规则FB-的contrib:SEO_SUBOPTIMAL_EXPRESSION_ORDER(注意,代码示例被简化,而不是逻辑的):fb-contrib的假阳性:SEO_SUBOPTIMAL_EXPRESSION_ORDER?

class Foo { 

    boolean baz; 

    boolean foo() { 
     return bar() && baz==Baz.VALUE; //Violation of fb-contrib:SEO_SUBOPTIMAL_EXPRESSION_ORDER 
    } 

    boolean bar() { 
     return baz == Baz.VALUE_2; 
    } 

} 

enum Baz { 
    VALUE, VALUE2 
} 

性能 - 在有条件的次优方式 方法订单表达式(fb-contrib:SEO_SUBOPTIMAL_EXPRESSION_ORDER)

此方法构建一个条件表达式,例如,在if或while语句中,表达式包含简单局部变量比较以及方法调用的比较。表达式对这些命令进行排序,以便方法调用在简单局部变量比较之前进行。这会导致方法调用在不需要的情况下执行,因此可能导致大量代码被执行。通过对表达式进行排序,以便首先包含局部变量条件的简单条件,可以消除这种浪费。这假定方法调用没有副作用。如果该方法确实有副作用,那么将这些调用从条件中提取出来并首先执行它们,将值分配给局部变量可能是一个更好的主意。通过这种方式,您可以提示呼叫可能有副作用。

我认为规则实现查看实际表达式是否合理,以及如果内容是值检查然后不触发违规。

这是一个错误还是我错过了什么?

+0

'foo()'不是SonarQube给出的原因,性能不是最理想的,但是因为它可以写成'return false;'。 ;-) –

+0

;-)我试着尽可能简化我的例子,但你当然是对的。无视愚蠢的代码(无论如何,这是完全不同的违规行为) – Alix

回答

0

你几乎给出了答案你的问题已经:

这导致方法调用条件来执行时,他们并不需要,因此有可能会导致很多的代码,以执行没有。通过对表达式进行排序,以便首先包含局部变量条件的简单条件,可以消除这种浪费。

FB-的Contrib要你转身的表达:

boolean foo() { 
    return baz==Baz.VALUE && bar(); 
} 

这样,bar()只需如果baz==Baz.value执行。当然,这是编译器或JVM可能优化的东西,所以它可以归结为一个微基准来确定这种预防措施是否真的有必要。

但它在语法层面上是有意义的,因为调用方法通常是比值检查更昂贵。所以你不需要看内部方法来说明这一点。无论如何,编译器/ JVM内联行为的任何猜测都可能是错误的。