Hi,

some or all of these were pointed out as part of
https://bugs.openjdk.java.net/browse/JDK-8029019

There was a patch out for review early 2017. I'm not sure what happened
to that?

Either way I think it might make sense to get this small and trivial
enhancement separated out and fixed.

Thanks!

/Claes

On 2019-11-08 23:04, Сергей Цыпанов wrote:
Hello,

it seems like Method.getParameterTypes() is often misused in JDK (and beyond): 
array returned from the method is used only to acquire number of method params 
by retrieving array.length.
The problem here is that Method.getPatameterTypes() clones underlying array and 
returns the copy.
Instead we can use Method.getParameterCount() which doesn't allocate any 
additional memory but returns directly the length of underlying  array.

To measure probable performance difference I've created a benchmark for the 
most simple case when tested method has no parameters:

@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MethodToStringBenchmark {
   private Method method;

   @Setup
   public void setup() throws Exception { method = 
getClass().getMethod("toString"); }

   @Benchmark
   public int getParameterCount() { return method.getParameterCount(); }

   @Benchmark
   public int getParameterTypes() { return method.getParameterTypes().length; }
}

on my i7-7700 with JDK 11 it produces these results:


Benchmark                                                               Mode  
Cnt     Score    Error   Units

MethodToStringBenchmark.getParameterCount                               avgt   
25     2,528 ±  0,085   ns/op
MethodToStringBenchmark.getParameterCount:·gc.alloc.rate                avgt   
25    ≈ 10⁻⁴           MB/sec
MethodToStringBenchmark.getParameterCount:·gc.alloc.rate.norm           avgt   
25    ≈ 10⁻⁷             B/op
MethodToStringBenchmark.getParameterCount:·gc.count                     avgt   
25       ≈ 0           counts

MethodToStringBenchmark.getParameterTypes                               avgt   
25     7,299 ±  0,410   ns/op
MethodToStringBenchmark.getParameterTypes:·gc.alloc.rate                avgt   
25  1999,454 ± 89,929  MB/sec
MethodToStringBenchmark.getParameterTypes:·gc.alloc.rate.norm           avgt   
25    16,000 ±  0,001    B/op
MethodToStringBenchmark.getParameterTypes:·gc.churn.G1_Eden_Space       avgt   
25  2003,360 ± 91,537  MB/sec
MethodToStringBenchmark.getParameterTypes:·gc.churn.G1_Eden_Space.norm  avgt   
25    16,030 ±  0,045    B/op
MethodToStringBenchmark.getParameterTypes:·gc.churn.G1_Old_Gen          avgt   
25     0,004 ±  0,001  MB/sec
MethodToStringBenchmark.getParameterTypes:·gc.churn.G1_Old_Gen.norm     avgt   
25    ≈ 10⁻⁵             B/op
MethodToStringBenchmark.getParameterTypes:·gc.count                     avgt   
25  2380,000           counts
MethodToStringBenchmark.getParameterTypes:·gc.time                      avgt   
25  1325,000               ms

I've prepared a small patch to replace usage of getParameterTypes() with 
getParameterCount() where appropriate in java.base module.

The patch is attached.

Regards,
Sergey Tsypanov

Reply via email to