加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-14 05:54:29 所属栏目:Java 来源:网络整理
导读:通常的做法是将常量空数组返回值提取为静态常量.像这儿: public class NoopParser implements Parser { private static final String[] EMPTY_ARRAY = new String[0]; @Override public String[] supportedSchemas() { return EMPTY_ARRAY; } // ...} 据推
通常的做法是将常量空数组返回值提取为静态常量.像这儿:
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减慢了一点点.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读