Java 8带来了lambda的所有优点,使我们能够使用声明式样式进行编程。 但这真的免费吗? 我们是否应该担心必须为新的编程功能付出的代价?
这是一个我们可能要担心的例子。
考虑对这个简单类的实例进行排序:
private static class MyComparableInt{private int a,b,c,d;public MyComparableInt(int i) {a = i%2;b = i%10;c = i%1000;d = i;}public int getA() { return a; }public int getB() { return b; }public int getC() { return c; }public int getD() { return d; }
}
我们可以使用新的Java 8声明性语法进行排序,如下所示:
List<MyComparableInt> mySortedComparableList = myComparableList.stream().sorted(Comparator.comparing(MyComparableInt::getA).thenComparing(MyComparableInt::getB).thenComparing(MyComparableInt::getC).thenComparing(MyComparableInt::getD)).collect(Collectors.toList());
或者我们可以使用以下代码对旧方法进行排序(仍然使用lambdas):
List<MyComparableInt> mySortedComparableList = myComparableList.stream().sorted(MyComparableIntSorter.INSTANCE).collect(Collectors.toList());public enum MyComparableIntSorter implements Comparator<MyComparableInt>{INSTANCE;@Overridepublic int compare(MyComparableInt o1, MyComparableInt o2) {int comp = Integer.compare(o1.getA(), o2.getA());if(comp==0){comp = Integer.compare(o1.getB(), o2.getB());if(comp==0){comp = Integer.compare(o1.getC(), o2.getC());if(comp==0){comp = Integer.compare(o1.getD(), o2.getD());}}}return comp;}}
当我使用10m个对象运行此测试时,使用声明性语法进行排序的时间约为6.5s,而使用旧语法仅进行了1.5s的时间。 差不多是原来的四倍!
那么时间在哪里呢? 大概在thenComparing方法之间进行编组是开销。
有趣的是,如果您尝试完全相同的测试,但将int替换为String,则时间变化如下。 同样,对于10m个对象,使用新语法大约需要11.5s,而旧语法大约需要7s。 使用String时,当编组的重要性降低时,新语法仅花费旧语法的1.5倍。
总而言之,尽管新语法看起来不错并且表现力极佳,但是如果您担心性能,则应该坚持使用旧语法。
再一次,似乎没有免费的午餐!
翻译自: https://www.javacodegeeks.com/2015/01/java8-sorting-performance-pitfall.html