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

Сергей Цыпанов sergei.tsypanov at yandex.ru
Wed Nov 13 23:24:25 UTC 2019


Hello,

thanks for quick review!

Tagir Valeev from JetBrains comes with suggestion to improve compiler optimizations here https://youtrack.jetbrains.com/issue/IDEA-226474.

Rationale: in fact the cloned array could be a subject of allocation erasure as any property dereferenced from it can be dereferenced from original array:

Consider this test:

@Test
void join() {
  final Object[] objects = new Object[3];
  objects[0] = "azaza";
  objects[1] = 365;
  objects[2] = 9876L;

  final Object[] clone = objects.clone();

  assertEquals(objects.length, clone.length);
  assertSame(objects[0], clone[0]);
  assertSame(objects[1], clone[1]);
  assertSame(objects[2], clone[2]);
}

Optimizing compiler could drop allocation of clone and substitute its usage with original array, but as previous benchmark demonstrates it doesn't do that at least on JDK 11.

Is there a way I can develop a patch for compiler and is this mailing list is appropriate place to discuss compiler issues?

Regards,
Sergey Tsypanov


09.11.2019, 01:15, "Claes Redestad" <claes.redestad at oracle.com>:
> 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


More information about the core-libs-dev mailing list