Optimize sun.invoke.util.BytecodeDescriptor.unparse
Christoph Dreis
christoph.dreis at freenet.de
Thu Aug 20 04:41:55 UTC 2020
HI,
I hate pinging, but I would really appreciate it if someone finds the time to take a look at my suggestion below from last week.
Or is this maybe the wrong mailing list - given that it is in the "sun" root package?
Cheers,
Christoph
===== ORIGINAL MAIL =====
Hi,
I just stumbled upon sun.invoke.util.BytecodeDescriptor.unparse that seems to unnecessarily create a StringBuilder and checks for the given type to be of Object.class twice in certain scenarios.
When I apply the attached patch below with the following isolated benchmark:
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Thread)
public class MyBenchmark {
@State(Scope.Thread)
public static class BenchmarkState {
private Class<?> test = String.class; // long.class;
}
@Benchmark
public String unparseNew(BenchmarkState state) {
return BytecodeDescriptor.unparseNew(state.test);
}
@Benchmark
public String unparseOld(BenchmarkState state) {
return BytecodeDescriptor.unparseOld(state.test);
}
}
I get the following results:
String.class
Benchmark Mode Cnt Score Error Units
MyBenchmark.unparseNew avgt 10 47,207 ± 1,918 ns/op
MyBenchmark.unparseNew:·gc.alloc.rate.norm avgt 10 232,011 ± 0,002 B/op
MyBenchmark.unparseOld avgt 10 87,197 ± 22,843 ns/op
MyBenchmark.unparseOld:·gc.alloc.rate.norm avgt 10 384,020 ± 0,001 B/op
long.class
Benchmark Mode Cnt Score Error Units
MyBenchmark.unparseNew avgt 10 4,996 ± 0,022 ns/op
MyBenchmark.unparseNew:·gc.alloc.rate.norm avgt 10 ≈ 10⁻⁶ B/op
MyBenchmark.unparseOld avgt 10 13,303 ± 6,305 ns/op
MyBenchmark.unparseOld:·gc.alloc.rate.norm avgt 10 80,003 ± 0,001 B/op
As you can see the new way makes things allocation free for primitives and also improves normal classes.
It seems like a relatively trivial improvement. In case you think this is worthwhile, I would appreciate it if someone could sponsor the change.
Cheers,
Christoph
======= PATCH =======
--- a/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java Thu Aug 13 09:33:28 2020 -0700
+++ b/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java Thu Aug 13 19:27:26 2020 +0200
@@ -110,9 +110,13 @@
} else if (type == int.class) {
return "I";
}
- StringBuilder sb = new StringBuilder();
- unparseSig(type, sb);
- return sb.toString();
+ Wrapper basicType = Wrapper.forBasicType(type);
+ char c = basicType.basicTypeChar();
+ if (c != 'L') {
+ return basicType.basicTypeString();
+ } else {
+ return type.descriptorString();
+ }
}
More information about the core-libs-dev
mailing list