More efficient JSON decoders and encoders for records#762
Conversation
38ad7c5 to
2ccd5a9
Compare
| case (key, value) => | ||
| if (first) | ||
| first = false | ||
| if (first) first = false |
There was a problem hiding this comment.
Please avoid unrelated format changes
There was a problem hiding this comment.
It is my attempt to make this peace of code looks similar though different copies in JsonCodec.scala
| else { | ||
| out.write(',') | ||
| if (indent.isDefined) pad(indent_, out) | ||
| if (doPrettyPrint) pad(indent_, out) |
There was a problem hiding this comment.
I think the common case is not pretty printing. Should that not be the first branch?
There was a problem hiding this comment.
The branch prediction for the common (non pretty printing) case is a smaller issue comparing to overhead of .isDefined , .isEmpty virtual calls and sub subsequent equality comparison with None.
| } else { | ||
| val schema = field.schema match { | ||
| case l @ Schema.Lazy(_) => l.schema | ||
| case l: Schema.Lazy[_] => l.schema |
There was a problem hiding this comment.
Does this make a difference?
There was a problem hiding this comment.
Yes, It does. It allows to avoid .unapply call in Scala 3 that allocates a redundant instance of Option[Tuple1].
There was a problem hiding this comment.
In the last commit beside formatting I fixed redundant 2 variables generated by Scala 3 compiler for that place. Now the byte code decompiled to Java looks more clear for that piece of code:
Schema schema = field.schema();
if (schema instanceof Schema.Lazy) {
Schema.Lazy l = (Schema.Lazy)schema;
schema = l.schema();
}
BEWARE: Case classes with more than 22 fields for parsing and serialization use
Schema.GenericRecordthat under the hood uses transformation from/toListMap(the most inefficient Scala collection that hasO(n)complexity for lookups and inserts).Below are results of benchmarks for real-world message samples using JDK-21 on Intel® Core™ i7-11800H CPU @ 2.3GHz (max 4.6GHz)
Scala 2.13
Before:
After:
Scala 3.6.2
Before:
After: