⚠️
背景是刷CF,所以最高优先级是代码效率,其次是敲代码的效率,最后才是可读。而对于工程化,我水平低,我认为用不到。
背景
假设要对一个数组排序,或者有一个TreeSet需要指定顺序。
这里以下面这个类为例:
class Node {
int index, value;
public Node(int index, int value) {
this.index = index;
this.value = value;
}
}
定义一个这个类的TreeSet,将有下面两种写法
new TreeSet<>(Comparator.comparingInt((Node o) -> o.value).thenComparingInt(o -> o.index));
new TreeSet<>((o1, o2) -> o1.value != o2.value ? Integer.compare(o1.value, o2.value) : Integer.compare(o1.index, o2.index));
显然,第一种写法非常的美。但是,显然又很遗憾,第一种写法会慢……建议使用第二种写法。甚至第二种写法还是太慢了,直接o1.value - o2.value
。甚至更考虑把两个int塞到一个long里进行比较。
原因
总而言之,工程化程度太高,各种检查太多,调用栈也太深了。
comparingX类的方法往往要求传入一个lambda函数,同时其源码往往包含null的检查。如果要thenComparingX的话,那这个调用栈就更深了。那么第一种写法的调用栈大概是:
treeSet -> comparator_2 -> comparator_1 -> lambda_1 -> lambda_2
反过来第二种写法在调用栈就比较简单
treeSet -> comparator
在必要的逻辑都一样的情况下,第一种写法会多出一堆调用。自然就慢了。