2017-03-09 320 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內聯行爲的任何猜測都可能是錯誤的。