C2 does not elide the zeroing of the array in String.repeat()
Сергей Цыпанов
sergei.tsypanov at yandex.ru
Mon Sep 21 13:57:55 UTC 2020
Hello,
as it appears from https://shipilev.net/blog/2016/arrays-wisdom-ancients/ C2 sometimes can eliminate
zeroing of newly allocated array (particularly in ArrayList.toArray(T[])).
However in case of String.repeat() VM does not elide the zeroing of the array even in case when
repeated String is represented with 1 byte:
if (len == 1) {
final byte[] single = new byte[count];
Arrays.fill(single, value[0]);
return new String(single, coder);
}
Here we are sure that the array is localized and for sure will be completely filled, however zeroing is present.
When I run the benchmark [1] with fresh-built JDK it gives
(length) Mode Cnt Score Error Units
repeatOneByteString 8 avgt 50 14.020 ± 1.928 ns/op
repeatOneByteString 64 avgt 50 24.618 ± 2.712 ns/op
repeatOneByteString 128 avgt 50 36.555 ± 1.394 ns/op
repeatOneByteString 1024 avgt 50 134.731 ± 7.022 ns/op
then if in String.repeat() I replace
final byte[] single = new byte[count];
with
final byte[] single = StringConcatHelper.newArray(count);
where StringConcatHelper.newArray(int) delegates directly to UNSAFE.allocateUninitializedArray(Class, int),
the same benchmark demonstrates good improvement:
(length) Mode Cnt Score Error Units
repeatOneByteString 8 avgt 50 12.545 ± 0.164 ns/op
repeatOneByteString 64 avgt 50 18.393 ± 0.686 ns/op
repeatOneByteString 128 avgt 50 25.550 ± 0.378 ns/op
repeatOneByteString 1024 avgt 50 90.454 ± 1.015 ns/op
So the question is whether there's an issue in C2 (and whether it is fixeable) or not?
Originally the question appeared in https://mail.openjdk.java.net/pipermail/core-libs-dev/2020-September/068641.html
Cheers,
Sergey Tsypanov
1.
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Fork(jvmArgsAppend = {"-Xms2g", "-Xmx2g"})
public class MiscStringBenchmark {
@Benchmark
public String repeatOneByteString(Data data) {
return data.oneByteString.repeat(data.length);
}
@State(Scope.Thread)
public static class Data {
@Param({"8", "64", "128", "1024"})
private int length;
private final String oneByteString = "a";
}
}
More information about the hotspot-compiler-dev
mailing list