RFR: 8265075: Improve and simplify Class.resolveName()

Сергей Цыпанов github.com+10835776+stsypanov at openjdk.java.net
Wed Apr 14 11:49:58 UTC 2021


On Wed, 14 Apr 2021 11:41:09 GMT, Alan Bateman <alanb at openjdk.org> wrote:

>> In mentioned method this code snippet
>> 
>> int len = baseName.length() + 1 + name.length();
>> StringBuilder sb = new StringBuilder(len);
>> name = sb.append(baseName.replace('.', '/'))
>>         .append('/')
>>         .append(name)
>>         .toString();
>> 
>> 
>> can be simplified with performance improvement as
>> 
>> name = baseName.replace('.', '/') + '/' + name;
>> 
>> Also null check of `baseName` can be removed as Class.getPackageName() never returns null.
>> 
>> This benchmark
>> 
>> @State(Scope.Thread)
>> @BenchmarkMode(Mode.AverageTime)
>> @OutputTimeUnit(TimeUnit.NANOSECONDS)
>> @Fork(jvmArgsAppend = {"-Xms2g", "-Xmx2g"})
>> public class ResolveNameBenchmark {
>> 
>>   private final Class<? extends ResolveNameBenchmark> klazz = getClass();
>> 
>>   @Benchmark
>>   public Object original() {
>>     return original("com/tsypanov/ovn/ResolveNameBenchmark.class");
>>   }
>> 
>>   @Benchmark
>>   public Object patched() {
>>     return patched("com/tsypanov/ovn/ResolveNameBenchmark.class");
>>   }
>> 
>>   private String original(String name) {
>>     if (!name.startsWith("/")) {
>>       String baseName = getPackageName();
>>       if (baseName != null && !baseName.isEmpty()) {
>>         int len = baseName.length() + 1 + name.length();
>>         StringBuilder sb = new StringBuilder(len);
>>         name = sb.append(baseName.replace('.', '/'))
>>                 .append('/')
>>                 .append(name)
>>                 .toString();
>>       }
>>     } else {
>>       name = name.substring(1);
>>     }
>>     return name;
>>   }
>> 
>>   private String patched(String name) {
>>       if (!name.startsWith("/")) {
>>           String baseName = getPackageName();
>>           if (!baseName.isEmpty()) {
>>               return baseName.replace('.', '/') + '/' + name;
>>           }
>>           return name;
>>       }
>>       return name.substring(1);
>>   }
>> 
>>   private String getPackageName() {
>>     return klazz.getPackageName();
>>   }
>> }
>> 
>> demonstrates good improvement, especially as of memory consumption:
>> 
>>                                             Mode  Cnt     Score     Error   Units
>> 
>> original                                    avgt   50    57.974 ±   0.365   ns/op
>> original:·gc.alloc.rate                     avgt   50  3419.447 ±  21.154  MB/sec
>> original:·gc.alloc.rate.norm                avgt   50   312.006 ±   0.001    B/op
>> original:·gc.churn.G1_Eden_Space            avgt   50  3399.396 ± 149.836  MB/sec
>> original:·gc.churn.G1_Eden_Space.norm       avgt   50   310.198 ±  13.628    B/op
>> original:·gc.churn.G1_Survivor_Space        avgt   50     0.004 ±   0.001  MB/sec
>> original:·gc.churn.G1_Survivor_Space.norm   avgt   50    ≈ 10⁻³              B/op
>> original:·gc.count                          avgt   50   208.000            counts
>> original:·gc.time                           avgt   50   224.000                ms
>> 
>> patched                                     avgt   50    44.367 ±   0.162   ns/op
>> patched:·gc.alloc.rate                      avgt   50  2749.265 ±  10.014  MB/sec
>> patched:·gc.alloc.rate.norm                 avgt   50   192.004 ±   0.001    B/op
>> patched:·gc.churn.G1_Eden_Space             avgt   50  2729.221 ± 193.552  MB/sec
>> patched:·gc.churn.G1_Eden_Space.norm        avgt   50   190.615 ±  13.539    B/op
>> patched:·gc.churn.G1_Survivor_Space         avgt   50     0.003 ±   0.001  MB/sec
>> patched:·gc.churn.G1_Survivor_Space.norm    avgt   50    ≈ 10⁻⁴              B/op
>> patched:·gc.count                           avgt   50   167.000            counts
>> patched:·gc.time                            avgt   50   181.000                ms
>
> We can remove the check for baseName being null, that's a left over from iteration during JDK 9.

@AlanBateman should I then do it only for `Class.resolveName()` or everywhere we call `Class.getPackageName()`?

-------------

PR: https://git.openjdk.java.net/jdk/pull/3464


More information about the core-libs-dev mailing list