1dbe487077
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