[PATCH] Use byte[] instead of char[] in Integer.digits

Сергей Цыпанов sergei.tsypanov at yandex.ru
Mon Jul 27 08:46:08 UTC 2020


Hello, I'd like to contribute this trivial patch to JDK.

The idea behind it is that with compact strings we don't need char[] when all symbols are ASCII.

This allows to slightly reduce footprint of java.lang.Integer.class and drop casts from char to byte.

I've measured performance of patched code using Integer/Long.toString() and toHexString() methods for short and long values
and the patch is likely to improve it slightly, at least for Long:

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Fork(jvmArgsAppend = {"-Xms2g", "-Xmx2g", "-XX:+UseParallelGC"})
public class IntegerToString {
  @Benchmark
  public String integerToHexString(Data data) { return Integer.toHexString(data.value); }

  @Benchmark
  public String integerToString(Data data) { return Integer.toString(data.value); }

  @State(Scope.Thread)
  public static class Data {
    @Param({"0", "2147483647"}) private int value;
  }
}


Gives

Benchmark                                       (value)  Mode  Cnt   Score   Error  Units
IntegerToString.integerToHexString                    0  avgt   50   7.833 ± 0.172  ns/op
IntegerToString.integerToString                       0  avgt   50   7.550 ± 0.070  ns/op
IntegerToString.integerToHexString           2147483647  avgt   50  13.200 ± 0.268  ns/op
IntegerToString.integerToString              2147483647  avgt   50  17.028 ± 0.572  ns/op

after

Benchmark                                       (value)  Mode  Cnt   Score   Error  Units
IntegerToString.integerToHexString                    0  avgt   50   7.771 ± 0.410  ns/op
IntegerToString.integerToString                       0  avgt   50   7.779 ± 0.321  ns/op
IntegerToString.integerToHexString           2147483647  avgt   50  13.193 ± 0.450  ns/op
IntegerToString.integerToString              2147483647  avgt   50  16.641 ± 0.332  ns/op

As of Long the corresponding benchmark

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Fork(jvmArgsAppend = {"-Xms2g", "-Xmx2g", "-XX:+UseParallelGC"})
public class LongToString {
  @Benchmark
  public String longToHexString(Data data) { return Long.toHexString(data.longValue); }

  @Benchmark
  public String longToString(Data data) { return Long.toString(data.longValue); }

  @State(Scope.Thread)
  public static class Data {
    @Param({"0", "9223372036854775807"}) private long longValue;
  }
}


gives

before

LongToString.longToHexString                          0  avgt   50   7.711 ± 0.303  ns/op
LongToString.longToString                             0  avgt   50   7.321 ± 0.439  ns/op
LongToString.longToHexString        9223372036854775807  avgt   50  17.393 ± 0.515  ns/op
LongToString.longToString           9223372036854775807  avgt   50  30.192 ± 1.365  ns/op

after

LongToString.longToHexString                          0  avgt   50   7.796 ± 0.250  ns/op
LongToString.longToString                             0  avgt   50   6.497 ± 0.015  ns/op
LongToString.longToHexString        9223372036854775807  avgt   50  17.720 ± 0.914  ns/op
LongToString.longToString           9223372036854775807  avgt   50  27.089 ± 0.232  ns/op

Also I've included into that patch trivial change for Integer.IntegerCache where we can use local variable size
instead of c.length where c is array. This is likely to slightly improve startup time as this code is executed at class
loading time and likely to be executed in interpreter mode rather than beingcompiled by optimizing compiler.

Regards,
Sergey Tsypanov
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bytes.patch
Type: text/x-diff
Size: 2583 bytes
Desc: not available
URL: <https://mail.openjdk.java.net/pipermail/core-libs-dev/attachments/20200727/b2e6120f/bytes.patch>


More information about the core-libs-dev mailing list