On Wed, 30 Jun 2021 08:40:21 GMT, Сергей Цыпанов
<[email protected]> wrote:
> As of JDK 17 some of primitive wrappers, e.g. `Long`, `Integer`, `Double` and
> `Float` in their implementations of `Object.toString()` delegate to own
> utility `toString(primitive)` methods.
>
> Unlike those, `Boolean`, `Byte`, `Character` and `Short` just duplicate the
> contents of utility methods in implementations of `Object.toString()`.
>
> Yet another issue is a tiny discrepancy in implementation related to `Byte`
> and `Short` (see the first):
>
> public static String toString(byte b) {
> return Integer.toString((int)b, 10);
> }
>
> public String toString() {
> return Integer.toString((int)value);
> }
>
> Unlike in overriden method, In utility one they explicitly specify radix
> which can be skipped, as implementation of `Integer.toString(int,int)` has a
> fast-path for radix 10, ending in `Integer.toString(int)`. This
> simplification gives tiny improvement, see benchmark:
>
> @BenchmarkMode(Mode.AverageTime)
> @OutputTimeUnit(TimeUnit.NANOSECONDS)
> @Fork(jvmArgsAppend = {"-Xms2g", "-Xmx2g"})
> public class ByteToStringBenchmark {
> @Benchmark
> public String byteToString() {
> return Byte.toString((byte) 1);
> }
> }
>
> Results:
>
> before
>
> Benchmark Mode
> Cnt Score Error Units
> ByteToStringBenchmark.byteToString avgt
> 30 11,648 ± 1,906 ns/op
> ByteToStringBenchmark.byteToString:·gc.alloc.rate avgt
> 30 3288,576 ± 418,119 MB/sec
> ByteToStringBenchmark.byteToString:·gc.alloc.rate.norm avgt
> 30 48,001 ± 0,001 B/op
> ByteToStringBenchmark.byteToString:·gc.churn.G1_Eden_Space avgt
> 30 3301,804 ± 455,932 MB/sec
> ByteToStringBenchmark.byteToString:·gc.churn.G1_Eden_Space.norm avgt
> 30 48,158 ± 2,085 B/op
> ByteToStringBenchmark.byteToString:·gc.churn.G1_Survivor_Space avgt
> 30 0,004 ± 0,001 MB/sec
> ByteToStringBenchmark.byteToString:·gc.churn.G1_Survivor_Space.norm avgt
> 30 ≈ 10⁻⁴ B/op
> ByteToStringBenchmark.byteToString:·gc.count avgt
> 30 202,000 counts
> ByteToStringBenchmark.byteToString:·gc.time avgt
> 30 413,000 ms
>
> after
>
> Benchmark Mode
> Cnt Score Error Units
> ByteToStringBenchmark.byteToString avgt
> 30 10,016 ± 0,530 ns/op
> ByteToStringBenchmark.byteToString:·gc.alloc.rate avgt
> 30 3673,700 ± 167,450 MB/sec
> ByteToStringBenchmark.byteToString:·gc.alloc.rate.norm avgt
> 30 48,001 ± 0,001 B/op
> ByteToStringBenchmark.byteToString:·gc.churn.G1_Eden_Space avgt
> 30 3662,406 ± 205,978 MB/sec
> ByteToStringBenchmark.byteToString:·gc.churn.G1_Eden_Space.norm avgt
> 30 47,870 ± 1,750 B/op
> ByteToStringBenchmark.byteToString:·gc.churn.G1_Survivor_Space avgt
> 30 0,004 ± 0,002 MB/sec
> ByteToStringBenchmark.byteToString:·gc.churn.G1_Survivor_Space.norm avgt
> 30 ≈ 10⁻⁴ B/op
> ByteToStringBenchmark.byteToString:·gc.count avgt
> 30 224,000 counts
> ByteToStringBenchmark.byteToString:·gc.time avgt
> 30 358,000 ms
This pull request has now been integrated.
Changeset: 72145f3b
Author: Sergey Tsypanov <[email protected]>
Committer: Claes Redestad <[email protected]>
URL:
https://git.openjdk.java.net/jdk/commit/72145f3b9472c8f5f64f9b9ac93e3331e646f15a
Stats: 13 lines in 4 files changed: 4 ins; 0 del; 9 mod
8269665: Clean-up toString() methods of some primitive wrappers
Reviewed-by: redestad
-------------
PR: https://git.openjdk.java.net/jdk/pull/4633