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.redes...@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