Profiling the compilation of kotlinx.serialization, MaxStackFrameSizeAndLocalsCalculator
causes ~7% of the runtime to be spent in java.lang.Object.hashCode
This is through two uses:
- visitMaxs(..) has a pushed hashSet that causes ~2%
- labelWrappersMap used to attach additional data to asm Labels, causes ~ 5%
visitMaxs can use the existing SmartSet (not to be confused with SmartHashSet)
Analysis of the visitMaxs HashSet creation & sizes:
| What | Amount |
| calls to visitMaxs | 4416 |
| max pushed | 158 |
| median pushed | 4 |
| average pushed | 5.20 |
| stddev pushed | 7.66 |
| 90 percentile | 10 |
Analysis of labelWrappersMap creation & sizes:
| What | Amount |
| ------------------ | ------ |
| hashtables created | 4006 |
| max entries | 175 |
| median entries | 5 |
| average entries | 6.10 |
| stdev entries | 8.28 |
| 90 percentile | 11 |
testing with a non hash based map using an array for keys and an array for values
showed that the cost of MaxStackFrameSizeAndLocalsCalculator became neglible to
the overall running time.
SmartIdentityTable is a Map like structure that uses reference identity for keys.
It uses 2 arrays to store keys & values until the number of entries stored is larger than 10.
At that point it switches to using an IdentityHashMap.
This structure can be used instead of HashMap when reference identity can be used and
the number of entries inserted is small (<= 10) on average, drastically reducing the overhead
of calls to Object.hashCode
Between the two changes, compilation of kotlinx.serialization through kotlinc
commandline decreased from 14 seconds to 11 seconds on my machine
This call have interesting rules for resolution, see
`KtQualifiedExpression.elementChain` function and it's usages:
resolution results for such call can be omitted and be replaced with
some other information, while diagnostics will be reported from
builder-inference.
To mitigate this problem, we'll just skip this call from builder-inference
as such calls can't have type parameters anyway
#KT-32094 Fixed
This commit influences enum entries deserialization.
In particular, now we don't deserialize enum entry members,
but deserialize its supertype correctly (see test data changes).
Before this commit, explicit extension receiver type check was performed
during found candidates analysis (together with arguments type check etc.)
Now we do it just after candidate is found, and filter the candidate
out if explicit receiver type is inappropriate.
This commit slightly changes resolve semantics,
replacing WRONG_RECEIVER with UNRESOLVED_REFERENCE in certain situations.
However, it provides significant performance boost.