Hi Aleksey,

On 6/18/20 7:10 PM, Aleksey Shipilev wrote:
On 6/18/20 3:09 PM, Chris Hegarty wrote:
On 18 Jun 2020, at 13:43, Aleksey Shipilev <sh...@redhat.com> wrote:
Again, JDK-8247532 is the writing on the wall: we don't need 3rd party 
developers to tell if Record
serialization works fast in 15 -- we already know it does not.
I disagree. JDK-8247532 is under review and well on its way towards JDK 15 
(yes, during RDP 1).
My reading of Peter’s benchmark result is that Record deserialization *does 
work fast*.   What am
I missing.
JDK-8247532 is the evidence that Records serialization performance story is not 
clear.

Even if we disregard that after JDK-8247532 [1] Records are still 8% slower, 
the _existence_ of
JDK-8247532 indicates there are performance problems in the area. That evidence 
now needs to be
compensated by much more evidence to the contrary. (Yes, I contracted a lot of 
Bayesian thinking
from my statistician wife...)

(Here were several paragraphs of further thoughts, but I realized it basically 
repeats what I said
before.)

Let me just express my thoughts on the subject of preventing writes to final fields in records in connection to deserialization. In short, I don't think any serialization framework would need to have direct write access to record fields in order to be performant. Serialization frameworks need write access to final fields in classical classes mainly because fields are generally encapsulated. If classes don't implement special API (constructors, methods, annotations ...) to interface with serialization framework (like for example Jackson annotations, etc.) then serialization framework can only interface such classes on the level of fields.

Now records are very constrained classes. They have an always present API that can be used to interface with serialization frameworks. For each field, they poses a constructor parameter with the same name and type and are arranged so that the fields are set from the constructor parameters. So instead of allocating a "zero" instance and setting fields, one can just invoke a canonical constructor which does the same. Such invocation is equally performant as allocating instance and setting fields from outside the constructor.

What I did in JDK-8247532 was that I just optimized the code that transforms the bytes read from stream into values for arguments of the canonical constructor using method handle transformations. That part was slow and not the fact that records are deserialized using their canonical constructor. Every serialization framework that works on the level of fields has to do the transformation of stream encoded data to field values - how it does that is what differs it from the rest - the final mechanism how those values are stored into object fields is not what makes it unique or performant.

There is also a desire that record constructor(s) are the only way to create instances of records such that any validation logic in the constructor(s) can't get bypassed. Not even via deserialization of "forged" streams. That way we can have records that are safer without scarifying performance.

And BTW, according to latest JDK-8247532 webrev.06, Java deserialization of records is not slower but sometimes even faster than deserialization of equivalent classical classes.


Regards, Peter


Reply via email to