From 8f963bed7cc6585a43afbada99e415d5dd81096b Mon Sep 17 00:00:00 2001 From: Andrey Uskov Date: Wed, 15 Sep 2021 23:08:36 +0300 Subject: [PATCH] Optimized performance of recordPackageLookup #KT-47909 Fixed --- .../kotlin/incremental/LookupStorage.kt | 35 +++++++++++++++---- .../incremental/KotlinLookupLocation.kt | 26 +++++++------- 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/build-common/src/org/jetbrains/kotlin/incremental/LookupStorage.kt b/build-common/src/org/jetbrains/kotlin/incremental/LookupStorage.kt index bf100df6ea9..c8b8c8a3dba 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/LookupStorage.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/LookupStorage.kt @@ -224,13 +224,36 @@ class LookupTrackerImpl(private val delegate: LookupTracker) : LookupTracker { override val requiresPosition: Boolean get() = delegate.requiresPosition - override fun record(filePath: String, position: Position, scopeFqName: String, scopeKind: ScopeKind, name: String) { - val internedScopeFqName = interner.intern(scopeFqName) - val internedName = interner.intern(name) - val internedFilePath = pathInterner.intern(filePath) + var prevFilePath: String = "" + var prevPosition: Position? = null + var prevScopeFqName: String = "" + var prevScopeKind: ScopeKind? = null + var prevName: String = "" - lookups.putValue(LookupSymbol(internedName, internedScopeFqName), internedFilePath) - delegate.record(internedFilePath, position, internedScopeFqName, scopeKind, internedName) + // This method is very hot and sequential invocations usually have the same parameters. Thus we cache previous parameters + override fun record(filePath: String, position: Position, scopeFqName: String, scopeKind: ScopeKind, name: String) { + val nameChanged = if (name != prevName) { + prevName = interner.intern(name) + true + } else false + val fqNameChanged = if (scopeFqName != prevScopeFqName) { + prevScopeFqName = interner.intern(scopeFqName) + true + } else false + val filePathChanged = if (filePath != prevFilePath) { + prevFilePath = pathInterner.intern(filePath) + true + } else false + + val lookupChanged = nameChanged || fqNameChanged || filePathChanged + if (lookupChanged) { + lookups.putValue(LookupSymbol(prevName, prevScopeFqName), prevFilePath) + } + if (lookupChanged || prevPosition != position || prevScopeKind != scopeKind) { + prevPosition = position + prevScopeKind = scopeKind + delegate.record(prevFilePath, position, prevScopeFqName, scopeKind, prevName) + } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/incremental/KotlinLookupLocation.kt b/compiler/frontend/src/org/jetbrains/kotlin/incremental/KotlinLookupLocation.kt index 248972b9d9f..2cce4df6a18 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/incremental/KotlinLookupLocation.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/incremental/KotlinLookupLocation.kt @@ -24,18 +24,20 @@ import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.doNotAnalyze class KotlinLookupLocation(val element: KtElement) : LookupLocation { + val cachedLocation : LocationInfo? by lazy { + val containingJetFile = element.containingKtFile + + if (containingJetFile.doNotAnalyze != null) + null + else + object : LocationInfo { + override val filePath = containingJetFile.virtualFilePath + + override val position: Position + get() = getLineAndColumnInPsiFile(containingJetFile, element.textRange).let { Position(it.line, it.column) } + } + } override val location: LocationInfo? - get() { - val containingJetFile = element.containingKtFile - - if (containingJetFile.doNotAnalyze != null) return null - - return object : LocationInfo { - override val filePath = containingJetFile.virtualFilePath - - override val position: Position - get() = getLineAndColumnInPsiFile(containingJetFile, element.textRange).let { Position(it.line, it.column) } - } - } + get() = cachedLocation }