[PATCH] Enhancement proposal for usage of Method::getParameterTypes

Сергей Цыпанов sergei.tsypanov at yandex.ru
Fri Nov 8 22:04:27 UTC 2019


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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: getParamCount.patch
Type: text/x-diff
Size: 3558 bytes
Desc: not available
URL: <https://mail.openjdk.java.net/pipermail/core-libs-dev/attachments/20191109/a66db498/getParamCount.patch>


More information about the core-libs-dev mailing list