> On 23 Jun 2020, at 14:49, Peter Levart <peter.lev...@gmail.com> wrote: > > ... > > Ok, I'm going to push this to jdk15.
Thank you Peter. This is a really nice change. As a follow on, and not for JDK 15, I observe that Class::isRecord0 / JVM_IsRecord shows up as consuming a significant amount of time, more than 10%, in some runs of the deserialization benchmark. The isRecord implementation is a native method in the JVM, so relatively expensive to call. This shows an opportunity to improve the Class::isRecord implementation with a simple cache of the record-ness of the j.l.Class, as is done selectively with other particular aspects of a class’s state. There are various ways to implement this, but here is just one [*]. Running the deserialization benchmark with this change [*], gives the following results: Benchmark (length) Mode Cnt Score Error Units RecordSerializationBench.deserializeClasses 10 avgt 10 14.136 ± 0.841 us/op RecordSerializationBench.deserializeClasses 100 avgt 10 61.821 ± 1.279 us/op RecordSerializationBench.deserializeClasses 1000 avgt 10 519.473 ± 7.950 us/op RecordSerializationBench.deserializeRecords 10 avgt 10 13.781 ± 1.917 us/op RecordSerializationBench.deserializeRecords 100 avgt 10 54.061 ± 4.188 us/op RecordSerializationBench.deserializeRecords 1000 avgt 10 444.538 ± 13.940 us/op I think it is worth considering caching the record-ness state of a j.l.Class, as I’m sure it will be widely used in third-party serialization libraries, as well as by Java Serialization. -Chris. [*] diff -r 3a9521647349 src/java.base/share/classes/java/lang/Class.java --- a/src/java.base/share/classes/java/lang/Class.java Tue Jun 23 10:46:39 2020 +0100 +++ b/src/java.base/share/classes/java/lang/Class.java Tue Jun 23 17:11:35 2020 +0100 @@ -3712,9 +3712,17 @@ @jdk.internal.PreviewFeature(feature=jdk.internal.PreviewFeature.Feature.RECORDS, essentialAPI=false) public boolean isRecord() { - return getSuperclass() == JAVA_LANG_RECORD_CLASS && isRecord0(); + if (!isRecordCalled) { + isRecord = getSuperclass() == JAVA_LANG_RECORD_CLASS && isRecord0(); + isRecordCalled = true; + } + return isRecord; } + // cached record(ness) status + private transient boolean isRecord; + private transient boolean isRecordCalled; + // Fetches the factory for reflective objects private static ReflectionFactory getReflectionFactory() { if (reflectionFactory == null) {