From d7153446398fe692bd3634cdcf29030e4d0f4980 Mon Sep 17 00:00:00 2001 From: pyos Date: Mon, 22 Jul 2019 13:15:51 +0200 Subject: [PATCH] psi2ir: precompute sort keys when generating members On kotlinx.serialization, this improves the performace of the compiler with -Xuse-ir by about 5% (average of 30 runs after 10 warmup runs: 3096 ms -> 2970 ms, minimum: 3037 ms -> 2884 ms). Flamegraphs for comparison (careful, huge SVG images): https://drive.google.com/open?id=1BlIFN4ivSKrXjY6vZ0xkZymwucGc7bSI https://drive.google.com/open?id=1xIW2IvW7LMCaAe4P2dOGOG8nCcpWI9PW --- .../psi2ir/generators/ClassGenerator.kt | 26 +++++++++-- .../ir/util/StableDescriptorsComparator.kt | 45 ------------------- 2 files changed, 23 insertions(+), 48 deletions(-) delete mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/StableDescriptorsComparator.kt diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt index b148753f744..b06f73bc49f 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt @@ -24,7 +24,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.mapValueParameters import org.jetbrains.kotlin.ir.expressions.putTypeArguments import org.jetbrains.kotlin.ir.expressions.typeParametersCount -import org.jetbrains.kotlin.ir.util.StableDescriptorsComparator import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides import org.jetbrains.kotlin.ir.util.referenceFunction import org.jetbrains.kotlin.psi.KtClassOrObject @@ -37,6 +36,10 @@ import org.jetbrains.kotlin.psi.psiUtil.pureStartOffset import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor import org.jetbrains.kotlin.psi.synthetics.findClassDescriptor +import org.jetbrains.kotlin.renderer.ClassifierNamePolicy +import org.jetbrains.kotlin.renderer.DescriptorRenderer +import org.jetbrains.kotlin.renderer.DescriptorRendererModifier +import org.jetbrains.kotlin.renderer.OverrideRenderingPolicy import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter @@ -51,6 +54,23 @@ class ClassGenerator( declarationGenerator: DeclarationGenerator ) : DeclarationGeneratorExtension(declarationGenerator) { + companion object { + private val DESCRIPTOR_RENDERER = DescriptorRenderer.withOptions { + withDefinedIn = false + overrideRenderingPolicy = OverrideRenderingPolicy.RENDER_OPEN_OVERRIDE + includePropertyConstant = true + classifierNamePolicy = ClassifierNamePolicy.FULLY_QUALIFIED + verbose = true + modifiers = DescriptorRendererModifier.ALL + } + + fun List.sortedByRenderer(): List { + val rendered = map(DESCRIPTOR_RENDERER::render) + val sortedIndices = (0 until size).sortedWith(Comparator { i, j -> rendered[i].compareTo(rendered[j]) }) + return sortedIndices.map { this[it] } + } + } + fun generateClass(ktClassOrObject: KtPureClassOrObject): IrClass { val classDescriptor = ktClassOrObject.findClassDescriptor(this.context.bindingContext) val startOffset = ktClassOrObject.getStartOffsetOfClassDeclarationOrNull() ?: ktClassOrObject.pureStartOffset @@ -125,7 +145,7 @@ class ClassGenerator( it?.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE } } - .sortedWith(StableDescriptorsComparator) + .sortedByRenderer() .forEach { fakeOverride -> declarationGenerator.generateFakeOverrideDeclaration(fakeOverride, ktClassOrObject)?.let { irClass.declarations.add(it) } } @@ -137,7 +157,7 @@ class ClassGenerator( .getContributedDescriptors(DescriptorKindFilter.CALLABLES) .filterIsInstance() .filter { it.kind == CallableMemberDescriptor.Kind.DELEGATION } - .sortedWith(StableDescriptorsComparator) + .sortedByRenderer() if (delegatedMembers.isEmpty()) return for (ktEntry in ktSuperTypeList.entries) { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/StableDescriptorsComparator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/StableDescriptorsComparator.kt deleted file mode 100644 index d482fba6fa1..00000000000 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/StableDescriptorsComparator.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.ir.util - -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.renderer.ClassifierNamePolicy -import org.jetbrains.kotlin.renderer.DescriptorRenderer -import org.jetbrains.kotlin.renderer.DescriptorRendererModifier -import org.jetbrains.kotlin.renderer.OverrideRenderingPolicy -import java.util.* - -object StableDescriptorsComparator : Comparator { - override fun compare(member1: DeclarationDescriptor?, member2: DeclarationDescriptor?): Int { - if (member1 == member2) return 0 - if (member1 == null) return -1 - if (member2 == null) return 1 - - val image1 = DESCRIPTOR_RENDERER.render(member1) - val image2 = DESCRIPTOR_RENDERER.render(member2) - return image1.compareTo(image2) - } - - private val DESCRIPTOR_RENDERER = DescriptorRenderer.withOptions { - withDefinedIn = false - overrideRenderingPolicy = OverrideRenderingPolicy.RENDER_OPEN_OVERRIDE - includePropertyConstant = true - classifierNamePolicy = ClassifierNamePolicy.FULLY_QUALIFIED - verbose = true - modifiers = DescriptorRendererModifier.ALL - } -} \ No newline at end of file