Java – performance advantages of static empty array instances

The usual approach is to extract the return value of an empty array of constants as static constants Like here:

public class NoopParser implements Parser {
    private static final String[] EMPTY_ARRAY = new String[0];

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

    // ...
}

Presumably, this is for performance reasons, because returning a new string [0] directly each time the method is called creates a new array object - but does it really?

I've always wondered if this really has a measurable performance advantage, or if it's just outdated folk wisdom Empty arrays are immutable Can VM not roll all empty string components into one? Can VM basically use the new string [0] for free?

Compare this exercise with returning an empty string: we are usually happy to write back ""; Instead of returning empty_ STRING;.

Solution

I benchmarked it with 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.

Environment (see after 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

Eliminatealocations is enabled by default (see Java - XX: printflagsfinal - version | grep eliminatealocations)

result:

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

Using constants is almost twice as fast

Closing eliminateallocations slowed down a little

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>