[英]Inline comparator vs custom comparator in Java
When sorting a list, is there any performance difference between using a java Comparator in-line (with an anonymous inner class) vs implementing a separate custom Comparator class? 排序列表时,使用java Comparator内联(使用匿名内部类)与实现单独的自定义Comparator类之间是否有任何性能差异?
1. 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. 2。
Collections.sort(list, new Comparator<WorkflowError>() {
public int compare(WorkflowError obj1, WorkflowError obj2) {
return obj1.getErrorCode().compareTo(obj2.getErrorCode());
}
});
Also, when will the compare()
method be invoked? 此外,何时调用
compare()
方法?
There's also option 3 - a lambda Function
: 还有选项3 - lambda
Function
:
Collections.sort(list, (a, b) -> a.getErrorCode().compareTo(b.getErrorCode()));
which should be about 2 x faster, according to this benchmark data . 根据这个基准数据 ,它应该快2倍左右。
... or (thanks to @JB Nizet ) option 4: ......或(感谢@JB Nizet )选项4:
list.sort(Comparator.comparing(WorkflowError::getErrorCode))
There's shouldn't be any performance difference between the two variations, since anonymous classes should produce identical byte code as regular classes (assuming they have the same source code). 这两个变体之间不应该有任何性能差异,因为匿名类应该生成与常规类相同的字节代码(假设它们具有相同的源代码)。 The only difference is that they'll have a generated name.
唯一的区别是他们将生成一个名称。
The compare
method will be invoked by Collections.sort
whenever it needs to compare two elements of the List to be sorted. 只要需要比较要排序的List的两个元素,
Collections.sort
就会调用compare
方法。
I made a little test and found no difference (just in some small run the inline comparator shows a slightly better performace). 我做了一个小测试,发现没有区别(只是在一些小的运行中,内联比较器显示稍微更好的性能)。 This is the code used to make the test:
这是用于进行测试的代码:
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;
}
}
Comparator class: 比较类:
public class MyComparatorOne implements Comparator<A> {
public int compare(A obj1, A obj2) {
return obj1.getVal().compareTo(obj2.getVal());
}
}
and the output is: 输出是:
List with 1000000 elements and 10000 runs
external Comparator class average millis: 3
inline Comparator class average millis: 3
If you have several invocation to the comparator keeping an instance of it would be helpful 如果您有几次调用比较器,保持它的实例将是有帮助的
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.