簡體   English   中英

相等性測試順序會影響Java的性能嗎?

[英]Does equality test order affect performance in Java?

我通常會發現自己在編寫這樣的代碼:

private List<Foo> fooList = new ArrayList<Foo>();

public Foo findFoo(FooAttr attr) {
    for(Foo foo : fooList) {
        if (foo.getAttr().equals(attr)) {
            return foo;
        }
    }
}

但是,假設我正確地防止了空輸入,我還可以這樣表達循環:

for(Foo foo : fooList) {
    if (attr.equals(foo.getAttr()) {
        return foo;
    }
}

我想知道上面的一種形式是否比另一種形式具有性能優勢。 我很清楚過早優化的危險,但是在這種情況下,我認為代碼無論哪種方式都清晰易讀,因此我正在尋找一個偏愛一種形式而不是另一種形式的理由,以便養成自己的編碼習慣,贊成那種形式。 我認為,如果列表足夠大,那么即使是很小的性能優勢也可能會花費大量時間。

特別是,我想知道第二種形式是否會更高效,因為equals()方法是在同一對象而不是不同對象上重復調用的? 也許分支預測是一個因素?

我會在這里提供2條建議:

  1. 測量它
  2. 如果沒有其他指向您的方向,請選擇一種在您大聲說出來(或在您的頭上!)時最有意義且聽起來最自然的形式。

我認為考慮分支預測會擔心效率太低。 但是,我發現代碼的第二個示例更具可讀性,因為您將一致對象放在第一位。 同樣,如果你比較this給一些其他的對象that ,我會把this第一。

當然,equals由程序員定義,因此它可能是不對稱的。 您應該使等價關系成為現實,所以情況並非如此。 即使您具有等價關系,順序也可能很重要。 假設attr是各種foo.getAttr的超類,並且equals方法的第一個測試將檢查另一個對象是否是同一類的實例。 然后attr.equals(foo.getAttr())將通過第一次檢查,但是foo.getAttr().equals(attr)將通過第一次檢查。

但是,很少擔心在此級別上具有效率。

這取決於equals方法的實現。 在這種情況下,我假設兩個對象都是同一類的實例。 因此,這意味着方法是平等的。 沒有任何性能差異

如果兩個對象屬於同一類型,則它們應執行相同的操作。 如果不是這樣,那么您將無法真正預先知道會發生什么,但是通常它會很快停止(使用instanceof或其他方法)。

對於我自己,我通常以對給定參數進行非空檢查來啟動該方法,然后使用attr.equals(foo.getAttr())因為在循環中不必檢查是否為空。 我猜只是一個偏愛的問題。

唯一會影響性能的是什么都不做的代碼。

在某些情況下,您所使用的代碼幾乎相同或相差如此之小,以至於無所謂。 就是這種情況。

交換.equals()有用的地方是,當您擁有一個已知類型的已知值且該值不能為null (此處似乎不是這種情況)時。

例如

Object o = (Integer) 123;
String s = "Hello";

o.equals(s); // the type of equals is unknown and a virtual table look might be required
s.equals(o); // the type of equals is known and the class is final.

差別是如此之小,我不會擔心。

DEVENTER(n)很難做出決定,因為它很少依賴該決定,例如在公園中漫步的方式

-道格拉斯·亞當斯(Douglas Adams)和約翰·勞埃德(John Lloyd)的《里夫(Liff)》的深層含義。

性能應該是相同的,但就安全性而言,通常最好讓左操作數為您確定不為null的值,並讓equals方法處理null值。

舉個例子:

String s1 = null;
s1.equals("abc");
"abc".equals(s1);

兩次調用equals不相等,因為一個調用將發出NullPointerException(第一個),另一個將返回false。

正是由於這個原因,通常優選使用后一種形式與字符串常量進行比較。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM