。
-
Lambda表达式在大多数虚拟机中采用invokeDynamic指令实现,相对于匿名内部类在效率上会更高一些。
List<User> userList = ...;Collections.sort(userList, (user1, user2) -> {
Long userId1 = user1.getId();
Long userId2 = user2.getId();
...
return userId1.compareTo(userId2);
});
-
2.5.尽量指定类的final修饰符
为类指定final修饰符,可以让该类不可以被继承。如果指定了一个类为final,则该类所有的方法都是final的,Java编译器会寻找机会内联所有的final方法。内联对于提升Java运行效率作用重大,具体可参见Java运行期优化,能够使性能平均提高50%。
反例:
public class DateHelper { }
正例:public final class DateHelper { ...
}
注意:使用Spring的AOP特性时,需要对Bean进行动态代理,如果Bean类添加了final修饰,会导致异常
3.1.把跟类成员变量无关的方法声明成静态方法
public static int getHeight(){}
3.4.协议方法参数值非空,避免不必要的空指针判断
协议编程,可以@NonNull和@Nullable标注参数,是否遵循全凭调用者自觉。
public static boolean isValide(@NotNull User user){..... return true}
3.5.协议方法返回值非空,避免不必要的空指针判断
协议编程,可以@NonNull和@Nullable标注参数,是否遵循全凭实现者自觉。
public interface OrderService{
@NonNull
public User getUser(int userID)
}
被调用方法已支持判空处理,调用方法无需再进行判空处理
UserDO user = JSON.parseObject(value, UserDO.class);
3.7.尽量避免不必要的函数封装
方法调用会引起入栈和出栈,导致消耗更多的CPU和内存,应当尽量避免不必要的函数封装。当然,为了使代码更简洁、更清晰、更易维护,增加一定的方法调用所带来的性能损耗是值得的。
3.8.尽量指定方法的final修饰符
方法指定final修饰符,可以让方法不可以被重写,Java编译器会寻找机会内联所有的final方法。内联对于提升Java运行效率作用重大,具体可参见Java运行期优化,能够使性能平均提高50%。
注意:所有的private方法会隐式地被指定final修饰符,所以无须再为其指定final修饰符。
4.3.尽量使用移位来代替正整数乘除
用移位操作可以极大地提高性能。对于乘除2^n(n为正整数)的正整数计算,可以用移位操作来代替。
int count=a < <10; 2的十次方 1024
4.4.提取公共表达式,避免重复计算
4.5.尽量不在条件表达式中用!取反 if (!(a >= 10)) { if (a < 10) {
if-else语句,每个if条件语句都要加装计算,直到if条件语句为true为止。switch语句进行了跳转优化,Java中采用tableswitch或lookupswitch指令实现,对于多常量选择分支处理效率更高。经过试验证明:在每个分支出现概率相同的情况下,低于5个分支时if-else语句效率更高,高于5个分支时switch语句效率更高。
5.2.尽量使用字符替换字符串
字符串的长度不确定,而字符的长度固定为1,查找和匹配的效率自然提高了。
String target=soure.repalce(':',‘+’)
6.1 不要使用循环拷贝数组,尽量使用System.arraycopy拷贝数组
7.7.尽量使用HashSet判断值存在
在Java集合类库中,List的contains方法普遍时间复杂度是O(n),而HashSet的时间复杂度为O(1)。如果需要频繁调用contains方法查找数据,可以先将List转换成HashSet。
Hastable 的查找性能 == HashSet 的查找性能,用不了 HashSet 可以用 Hashtable 替换。
8.2.尽量避免在循环中捕获异常
9.2.尽量重复使用同一缓冲区 setLenth缓冲区从0开始
9.3.尽量设计使用同一缓冲区
为了提高程序运行效率,在设计上尽量使用同一缓冲区。
9.4.尽量使用缓冲流减少IO操作
使用缓冲流BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream等,可以大幅较少IO次数并提升IO速度。
10.1.在单线程中,尽量使用非线程安全类
使用非线程安全类,避免了不必要的同步开销。
反例:
StringBuffer buffer = new StringBuffer(128);
buffer.append("select * from ").append(T_USER).append(" where id = ?");
正例:
StringBuilder buffer = new StringBuilder(128);
buffer.append("select * from ").append(T_USER).append(" where id = ?");
10.2.在多线程中,尽量使用线程安全类
使用线程安全类,比自己实现的同步代码更简洁更高效。
反例:
private volatile int counter = 0;
public void access(Long userId) {
synchronized (this) {
counter++;
}
...
}
正例:
private final AtomicInteger counter = new AtomicInteger(0);
public void access(Long userId) {
counter.incrementAndGet();
...
}
同步代码块是有性能开销的,如果确定可以合并为同一同步代码块,就应该尽量合并为同一同步代码块。// 处理单一订单
public handleOrder(OrderDO order) {
...
}
// 处理所有订单
public synchronized void handleOrder(List<OrderDO> orderList) {
for (OrderDO order : orderList) {
handleOrder(order);
}
}
10.5.尽量使用线程池减少线程开销