转载

9个小技巧提升你的Java性能

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

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

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

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

1 、在构造函数中实例化

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

// Slower :walking:‍♂️
Set<String> set = new HashSet<>();
set.addAll(Arrays.asList("one", "two", "three"));

// Faster :rocket:
Set<String> 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 :rocket: > ~148,344 op/s
@Benchmark
public HashSet usingConstructor() {
    var set = new HashSet<>(list);
    return set;
}

// Slower :walking:‍♂️ > ~112,061 op/s
@Benchmark
public HashSet usingAddAll() {
    var set = new HashSet<>();
    set.addAll(list);
    return set;
}

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

2、 addAlladd 更快

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

// Slower :walking:‍♂️ ~116116op/s
@Benchmark
public ArrayList<Integer> usingAdd() {
    var a = new int[1000];
    for (var i = 0; i < 1000; i++) {
        a[i] = i;
    }

    var arr = new ArrayList<Integer>();
    for (var i = 0; i < 1000; i++) {
        arr.add(a[i]);
    }

    return arr;
}

// Faster :rocket: ~299130 op/s
@Benchmark
public ArrayList<Integer> usingAddAll() {
    var a = new Integer[1000];
    for (var i = 0; i < 1000; i++) {
        a[i] = i;
    }
    
    var arr = new ArrayList<Integer>();
    arr.addAll(Arrays.asList(a));
    return arr;
}

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

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

// Slower :walking:‍♂️ ~37000 op/s
@Benchmark
public HashMap<Integer, Integer> keySetIteration(Blackhole blackhole) {
    var someMap = new HashMap<Integer, Integer>();

    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 :rocket: ~45000 op/s
@Benchmark
public HashMap<Integer, Integer> entrySetIteration(Blackhole blackhole) {
    var someMap = new HashMap<Integer, Integer>();

    for (var i = 0; i < 1000; i++) {
        someMap.put(i, i);
    }

    var sum = 0;
    for(Map.Entry<Integer, Integer> e: someMap.entrySet()) {
        sum += e.getKey();
        sum += e.getValue();
    }

    blackhole.consume(sum);

    return someMap;
}

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

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

// Faster :rocket:
var list = Collections.singletonList("S"); 

// Slower :walking:‍♂️
var list = new ArrayList(Arrays.asList("S"));

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

// Faster :rocket:
public enum Color {
    RED, YELLOW, GREEN
}

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

// Slower :walking:‍♂️
var colors = new HashSet<>(Arrays.asList(Color.values()));

关于更多 EnumSet 看 这里

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

// Faster :rocket:
 var i = 0 ;
 i += addSomeNumber();
 i -= minusSomeNumber();
 return i;

 // Slower :walking:‍♂️
 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 :rocket:
 var r = 'R' ;
 var g = 'G' ;
 var b = 'B' ;

 // Slower :walking:‍♂️
 var r = "R" ;
 var g = "G" ;
 var b = "B" ;

9、尽可能使用StringBuilder

// Faster :rocket:
StringBuilder str = new StringBuilder(); 
str.append("A"); 
str.append("B"); 
str.append("C"); 
str.append("D"); 
str.append("E"); 
....

// Slower :walking:‍♂️
var str = "";
str += "A";
str += "B";
str += "C";
str += "D";
str += "E";
....

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

原文  https://segmentfault.com/a/1190000019864841
正文到此结束
Loading...