java 小技巧_9个小技巧提升你的Java性能

任何傻瓜都能写出计算机可以理解的代码, 但只有优秀的程序眼才能写出人类可以理解的代码 — Martin Fowler

但是总有渴望编写高性能代码的程序员存在吧,让我们来看看如何编写运行更快的Java代码吧!

注意:JVM对代码进行了有效的优化。因此,您不需要针对一般用例对其进行优化。但是,如果您想让JVM发挥最大性能。我们开始吧。

所有测试用例都在Macbook Pro 2015的Java12 HotSpot(TM) 64-Bit Server VM上运行

1 、在构造函数中实例化

如果你的Collections只初始化一次,则最好集合构造器中对它的值进行初始化,而不是实例化集合后使用addall或add方法设置值.

// Slower 🚶‍♂️

Set set = new HashSet<>();

set.addAll(Arrays.asList("one", "two", "three"));

// Faster 🚀

Set set = new HashSet<>(Arrays.asList("one", "two", "three"));

让我们使用JMH基准测试来验证一下

结果的单位是每秒操作的次数(op/s),数值越大,性能越高

@State(Scope.Thread)

public static class MyState {

@Setup(Level.Trial)

public void doSetup() {

var arr = new Integer[100000];

for (var i = 0; i < 100000; i++) {

arr[i] = i;

}

list = Arrays.asList(arr);

}

public List list;

}

// Faster 🚀 > ~148,344 op/s

@Benchmark

public HashSet usingConstructor() {

var set = new HashSet<>(list);

return set;

}

// Slower 🚶‍♂️ > ~112,061 op/s

@Benchmark

public HashSet usingAddAll() {

var set = new HashSet<>();

set.addAll(list);

return set;

}

construtor版本比addall版本提供~36000 op/s

2、addAll比add更快

同样的,addAll比add每秒提供更高的操作次数,所以下次当你向数组中添加的时,一定要先把它们收集起来,然后用addAll添加.

// Slower 🚶‍♂️ ~116116op/s

@Benchmark

public ArrayList usingAdd() {

var a = new int[1000];

for (var i = 0; i < 1000; i++) {

a[i] = i;

}

var arr = new ArrayList();

for (var i = 0; i < 1000; i++) {

arr.add(a[i]);

}

return arr;

}

// Faster 🚀 ~299130 op/s

@Benchmark

public ArrayList usingAddAll() {

var a = new Integer[1000];

for (var i = 0; i < 1000; i++) {

a[i] = i;

}

var arr = new ArrayList();

arr.addAll(Arrays.asList(a));

return arr;

}

addall的速度几乎是add版本的两倍。

3、遍历Map使用EntrySet,不要再使用KeySet

// Slower 🚶‍♂️ ~37000 op/s

@Benchmark

public HashMap keySetIteration(Blackhole blackhole) {

var someMap = new HashMap();

for (var i = 0; i < 1000; i++) {

someMap.put(i, i);

}

var sum = 0;

for(Integer i: someMap.keySet()) {

sum += i;

sum += someMap.get(i);

}

blackhole.consume(sum);

return someMap;

}

// Faster 🚀 ~45000 op/s

@Benchmark

public HashMap entrySetIteration(Blackhole blackhole) {

var someMap = new HashMap();

for (var i = 0; i < 1000; i++) {

someMap.put(i, i);

}

var sum = 0;

for(Map.Entry e: someMap.entrySet()) {

sum += e.getKey();

sum += e.getValue();

}

blackhole.consume(sum);

return someMap;

}

EntrySet在一秒钟内可以运行9000个操作,远超它的变种KeySet

4、使用SingleList代替只有单个元素的数组

// Faster 🚀

var list = Collections.singletonList("S");

// Slower 🚶‍♂️

var list = new ArrayList(Arrays.asList("S"));

5、使用EnumSet代替Hashset, EnumSet更快

// Faster 🚀

public enum Color {

RED, YELLOW, GREEN

}

var colors = EnumSet.allOf(Color.class);

// Slower 🚶‍♂️

var colors = new HashSet<>(Arrays.asList(Color.values()));

关于更多EnumSet看这里

6、不要随意的初始化对象,尽量重复使用

// Faster 🚀

var i = 0 ;

i += addSomeNumber();

i -= minusSomeNumber();

return i;

// Slower 🚶‍♂️

var i = 0 ;

var j = addSomeNumber();

var k = minusSomeNumber();

var l = i + j - k;

return l;

7、使用String.isEmpty()方法来检查字符串是否为空

因为String是一个byte[],isEmpty方法只是检查数组的长度,所以更快

public boolean isEmpty() {

return value.length == 0;

}

8、如果使用只有一个字符的字符串,请用单引号代替双引号

// Faster 🚀

var r = 'R' ;

var g = 'G' ;

var b = 'B' ;

// Slower 🚶‍♂️

var r = "R" ;

var g = "G" ;

var b = "B" ;

9、尽可能使用StringBuilder

// Faster 🚀

StringBuilder str = new StringBuilder();

str.append("A");

str.append("B");

str.append("C");

str.append("D");

str.append("E");

....

// Slower 🚶‍♂️

var str = "";

str += "A";

str += "B";

str += "C";

str += "D";

str += "E";

....

特别当你需要连接字符串的时候,使用StringBuilder比+更快

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值