簡體   English   中英

Java中的內聯比較器與自定義比較器

[英]Inline comparator vs custom comparator in Java

排序列表時,使用java Comparator內聯(使用匿名內部類)與實現單獨的自定義Comparator類之間是否有任何性能差異?

1。

public class SortByErrorComparator implements Comparator<WorkflowError> {
    public int compare(WorkflowError obj1, WorkflowError obj2) {
        return obj1.getErrorCode().compareTo(obj2.getErrorCode());
    }
}
Collections.sort(list, new SortByErrorComparator()) ;

2。

Collections.sort(list, new Comparator<WorkflowError>() {
    public int compare(WorkflowError obj1, WorkflowError obj2) {
        return obj1.getErrorCode().compareTo(obj2.getErrorCode());
    }
});

此外,何時調用compare()方法?

還有選項3 - lambda Function

Collections.sort(list, (a, b) -> a.getErrorCode().compareTo(b.getErrorCode()));

根據這個基准數據 ,它應該快2倍左右。

......或(感謝@JB Nizet )選項4:

list.sort(Comparator.comparing(WorkflowError::getErrorCode))

這兩個變體之間不應該有任何性能差異,因為匿名類應該生成與常規類相同的字節代碼(假設它們具有相同的源代碼)。 唯一的區別是他們將生成一個名稱。

只要需要比較要排序的List的兩個元素, Collections.sort就會調用compare方法。

我做了一個小測試,發現沒有區別(只是在一些小的運行中,內聯比較器顯示稍微更好的性能)。 這是用於進行測試的代碼:

public class ComparatorTest {

    private static final int MAX = 1000000;
    private static final int RUN = 10000;

    public static void main(String[] args) {

        List<A> list = new ArrayList<A>();

        long externalComparatorClassTotalTime = 0;
        long inlineCompartorTotalTime = 0;

        for (int i = RUN; i > 0; i--) {
            init(list);
            externalComparatorClassTotalTime += externalComparatorClassTest(list);
            init(list);
            inlineCompartorTotalTime += inlineCompartorTest(list);
        }

        System.out.format("List with %d elements and %d runs%n", MAX, RUN);
        System.out.println("external Comparator class average millis: " + externalComparatorClassTotalTime / RUN);
        System.out.println("inline Comparator class average millis: " + inlineCompartorTotalTime / RUN);
    }

    private static void init(List<A> list) {
        list.clear();
        for (int i = MAX; i > 0; i--) {
            list.add(new A(i));
        }
    }

    private static long inlineCompartorTest(List<A> secondList) {
        long start = System.currentTimeMillis();

        Collections.sort(secondList, new Comparator<A>() {
                public int compare(A obj1, A obj2) {
                    return obj1.getVal().compareTo(obj2.getVal());
                }
        });

        return System.currentTimeMillis() - start;
    }

    private static long externalComparatorClassTest(List<A> firstList) {
        long start = System.currentTimeMillis();

        Collections.sort(firstList, new MyComparatorOne());

        return System.currentTimeMillis() - start;
    }
}

比較類:

public class MyComparatorOne implements Comparator<A> {
    public int compare(A obj1, A obj2) {
        return obj1.getVal().compareTo(obj2.getVal());
    }
}

輸出是:

List with 1000000 elements and 10000 runs
external Comparator class average millis: 3
inline Comparator class average millis: 3

如果您有幾次調用比較器,保持它的實例將是有幫助的

暫無
暫無

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

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