Hi, Sergey!

Have you measured the code change in the java.lang.Class itself or just equivalent code in the JMH test as you show us?


The JMH test may show better results as it is compiled to bytecode that uses special invokedynamic-based string concatenation with optimal MH based underlying strategy. The code in java.lang.Class can't be compiled to use this kind of concatenation because of bootstraping issues and is therefore compiled to bytecode that uses StringBuilder directly (much like the existing code of the patched method). So I'm wondering whether the improvement in speed is actually there...


Regards, Peter


On 4/13/21 2:55 PM, Сергей Цыпанов 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

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

Commit messages:
  - 8265075: Improve and simplify Class.resolveName()

Changes: https://git.openjdk.java.net/jdk/pull/3464/files
  Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=3464&range=00
   Issue: https://bugs.openjdk.java.net/browse/JDK-8265075
   Stats: 11 lines in 1 file changed: 0 ins; 7 del; 4 mod
   Patch: https://git.openjdk.java.net/jdk/pull/3464.diff
   Fetch: git fetch https://git.openjdk.java.net/jdk pull/3464/head:pull/3464

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

Reply via email to