java – 静态空数组实例的性能优势

前端之家收集整理的这篇文章主要介绍了java – 静态空数组实例的性能优势前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
通常的做法是将常量空数组返回值提取为静态常量.像这儿:
public class NoopParser implements Parser {
    private static final String[] EMPTY_ARRAY = new String[0];

    @Override public String[] supportedSchemas() {
        return EMPTY_ARRAY;
    }

    // ...
}

据推测这是出于性能原因,因为每次调用方法时直接返回新的String [0]会创建一个新的数组对象 – 但它真的会吗?

我一直想知道这样做是否真的有可衡量的性能优势,或者它是否只是过时的民间智慧.空数组是不可变的. VM是否无法将所有空String组件都卷成一个? VM可以基本上免费使用新的String [0]吗?

将此练习与返回空字符串进行对比:我们通常非常乐意写回“”;而不是返回EMPTY_STRING;.

解决方法

我用 JMH对它进行了基准测试:
private static final String[] EMPTY_STRING_ARRAY = new String[0];

@Benchmark
public void testStatic(Blackhole blackhole) {
    blackhole.consume(EMPTY_STRING_ARRAY);
}

@Benchmark
@Fork(jvmArgs = "-XX:-EliminateAllocations")
public void testStaticEliminate(Blackhole blackhole) {
    blackhole.consume(EMPTY_STRING_ARRAY);
}

@Benchmark
public void testNew(Blackhole blackhole) {
    blackhole.consume(new String[0]);
}

@Benchmark
@Fork(jvmArgs = "-XX:-EliminateAllocations")
public void testNewEliminate(Blackhole blackhole) {
    blackhole.consume(new String[0]);
}

@Benchmark
public void noop(Blackhole blackhole) {
}

Full source code.

环境(在java -jar target / benchmarks.jar -f 1之后看到):

# JMH 1.11.2 (released 51 days ago)
# VM version: JDK 1.7.0_75,VM 24.75-b04
# VM invoker: /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java
# VM options: <none>
# Warmup: 20 iterations,1 s each
# Measurement: 20 iterations,1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread,will synchronize iterations
# Benchmark mode: Throughput,ops/time

默认情况下,EliminateAllocations处于启用状态(见于java -XX:PrintFlagsFinal -version | grep EliminateAllocations).

结果:

Benchmark                         Mode  Cnt           score         Error  Units
MyBenchmark.testNewEliminate     thrpt   20    95912464.879 ± 3260948.335  ops/s
MyBenchmark.testNew              thrpt   20   103980230.952 ± 3772243.160  ops/s
MyBenchmark.testStaticEliminate  thrpt   20   206849985.523 ± 4920788.341  ops/s
MyBenchmark.testStatic           thrpt   20   219735906.550 ± 6162025.973  ops/s
MyBenchmark.noop                 thrpt   20  1126421653.717 ± 8938999.666  ops/s

使用常数几乎快两倍.

关闭EliminateAllocations减慢了一点点.

猜你在找的Java相关文章