From f0ba09ae40cdce58dae7d3d5cb30be478c879280 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Tue, 6 Sep 2016 15:23:42 +0300 Subject: [PATCH] Optimize deserialized scope members computation for non-existing names Do not use memoized function if member with given name is not contained in the scope There are a lot of queries with names of non-existent functions, that leads to many effectively redundant Map nodes in MemoizedFunction and also cause additional computation that is worth to compute at once Also drop unused 'location' parameter --- .../DeserializedClassDescriptor.kt | 14 ++++---- .../descriptors/DeserializedMemberScope.kt | 36 ++++++++++++++----- .../DeserializedPackageMemberScope.kt | 6 ++-- 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt index 2d0d870d5d9..db02e1a10a9 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt @@ -251,19 +251,19 @@ class DeserializedClassDescriptor( }) } - override fun getNonDeclaredFunctionNames(location: LookupLocation): Set { + override fun getNonDeclaredFunctionNames(): Set { return classDescriptor.typeConstructor.supertypes.flatMapTo(LinkedHashSet()) { - it.memberScope.getContributedDescriptors().filterIsInstance().map { it.name } - } + c.components.additionalClassPartsProvider.getFunctionsNames(this@DeserializedClassDescriptor) + it.memberScope.getFunctionNames() + }.apply { addAll(c.components.additionalClassPartsProvider.getFunctionsNames(this@DeserializedClassDescriptor)) } } - override fun getNonDeclaredVariableNames(location: LookupLocation): Set { + override fun getNonDeclaredVariableNames(): Set { return classDescriptor.typeConstructor.supertypes.flatMapTo(LinkedHashSet()) { - it.memberScope.getContributedDescriptors().filterIsInstance().map { it.name } + it.memberScope.getVariableNames() } } - override fun getNonDeclaredTypeAliasNames(location: LookupLocation): Set { + override fun getNonDeclaredTypeAliasNames(): Set { return classDescriptor.typeConstructor.supertypes.flatMapTo(LinkedHashSet()) { it.memberScope.getContributedDescriptors().filterIsInstance().map { it.name } } @@ -339,7 +339,7 @@ class DeserializedClassDescriptor( fun findEnumEntry(name: Name): ClassDescriptor? = enumEntryByName(name) - private fun computeEnumMemberNames(): Collection { + private fun computeEnumMemberNames(): Set { // NOTE: order of enum entry members should be irrelevant // because enum entries are effectively invisible to user (as classes) val result = HashSet() diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberScope.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberScope.kt index 2596c3e3c40..837b17cea20 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberScope.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberScope.kt @@ -64,6 +64,17 @@ abstract class DeserializedMemberScope protected constructor( private val typeAliases = c.storageManager.createMemoizedFunction> { computeTypeAliases(it) } + private val functionNamesLazy by c.storageManager.createLazyValue { + functionProtos.keys + getNonDeclaredFunctionNames() + } + + private val variableNamesLazy by c.storageManager.createLazyValue { + propertyProtos.keys + getNonDeclaredVariableNames() + } + + override fun getFunctionNames() = functionNamesLazy + override fun getVariableNames() = variableNamesLazy + private inline fun Collection.groupByName( getNameIndex: (M) -> Int ) = groupBy { c.nameResolver.getName(getNameIndex(it)) } @@ -93,7 +104,10 @@ abstract class DeserializedMemberScope protected constructor( protected open fun computeNonDeclaredFunctions(name: Name, functions: MutableCollection) { } - override fun getContributedFunctions(name: Name, location: LookupLocation): Collection = functions(name) + override fun getContributedFunctions(name: Name, location: LookupLocation): Collection { + if (name !in getFunctionNames()) return emptyList() + return functions(name) + } private fun computeProperties(name: Name) = computeDescriptors( @@ -113,9 +127,15 @@ abstract class DeserializedMemberScope protected constructor( { c.memberDeserializer.loadTypeAlias(it) }, { }) - override fun getContributedVariables(name: Name, location: LookupLocation): Collection = properties(name) + override fun getContributedVariables(name: Name, location: LookupLocation): Collection { + if (name !in getVariableNames()) return emptyList() + return properties(name) + } - protected fun getContributedTypeAliases(name: Name): Collection = typeAliases(name) + protected fun getContributedTypeAliases(name: Name): Collection { + if (name !in typeAliasNames) return emptyList() + return typeAliases(name) + } protected abstract fun addClassifierDescriptors(result: MutableCollection, nameFilter: (Name) -> Boolean) @@ -184,13 +204,13 @@ abstract class DeserializedMemberScope protected constructor( } protected fun addNonDeclaredDescriptors(result: MutableCollection, location: LookupLocation) { - result.addAll(getNonDeclaredFunctionNames(location).flatMap { getContributedFunctions(it, location) }) - result.addAll(getNonDeclaredVariableNames(location).flatMap { getContributedVariables(it, location) }) + result.addAll(getNonDeclaredFunctionNames().flatMap { getContributedFunctions(it, location) }) + result.addAll(getNonDeclaredVariableNames().flatMap { getContributedVariables(it, location) }) } - protected abstract fun getNonDeclaredFunctionNames(location: LookupLocation): Set - protected abstract fun getNonDeclaredVariableNames(location: LookupLocation): Set - protected abstract fun getNonDeclaredTypeAliasNames(location: LookupLocation): Set + protected abstract fun getNonDeclaredFunctionNames(): Set + protected abstract fun getNonDeclaredVariableNames(): Set + protected abstract fun getNonDeclaredTypeAliasNames(): Set protected abstract fun addEnumEntryDescriptors(result: MutableCollection, nameFilter: (Name) -> Boolean) diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedPackageMemberScope.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedPackageMemberScope.kt index bcfbef36ffb..c06ab7e2452 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedPackageMemberScope.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedPackageMemberScope.kt @@ -72,9 +72,9 @@ open class DeserializedPackageMemberScope( } } - override fun getNonDeclaredFunctionNames(location: LookupLocation): Set = emptySet() - override fun getNonDeclaredVariableNames(location: LookupLocation): Set = emptySet() - override fun getNonDeclaredTypeAliasNames(location: LookupLocation): Set = emptySet() + override fun getNonDeclaredFunctionNames(): Set = emptySet() + override fun getNonDeclaredVariableNames(): Set = emptySet() + override fun getNonDeclaredTypeAliasNames(): Set = emptySet() override fun addEnumEntryDescriptors(result: MutableCollection, nameFilter: (Name) -> Boolean) { // Do nothing