Merge sequent filter and map calls into one loop

ScopeTowerProcessors.kt contains a few code snippets
that look like `collectCandidates(...).filter { ... }.map { ... }`.
Filter argument is always side-effect free, so it is safe
to merge `filter` and `map` calls into one for-loop.

The change also makes sense, because modified functions are quite hot.
For example `NoExplicitReceiverScopeTowerProcessor.simpleProcess`
produces 11,392,768 ArrayList instances (~1.08% of all objects)
when compiling the compiler according to aprof at the moment of writing.

On my machine the change improves compilation speed of the compiler up to 5%.
This commit is contained in:
Alexey Tsvetkov
2017-04-09 23:38:50 +03:00
parent e25060f8c9
commit 2ff28ebced
@@ -64,15 +64,23 @@ internal class ExplicitReceiverScopeTowerProcessor<C: Candidate>(
} }
private fun resolveAsMember(): Collection<C> { private fun resolveAsMember(): Collection<C> {
val members = val members = mutableListOf<C>()
MemberScopeTowerLevel(scopeTower, explicitReceiver) for (memberCandidate in MemberScopeTowerLevel(scopeTower, explicitReceiver).collectCandidates(null)) {
.collectCandidates(null).filter { !it.requiresExtensionReceiver } if (!memberCandidate.requiresExtensionReceiver) {
return members.map { candidateFactory.createCandidate(it, ExplicitReceiverKind.DISPATCH_RECEIVER, extensionReceiver = null) } members.add(candidateFactory.createCandidate(memberCandidate, ExplicitReceiverKind.DISPATCH_RECEIVER, extensionReceiver = null))
}
}
return members
} }
private fun resolveAsExtension(level: ScopeTowerLevel): Collection<C> { private fun resolveAsExtension(level: ScopeTowerLevel): Collection<C> {
val extensions = level.collectCandidates(explicitReceiver).filter { it.requiresExtensionReceiver } val extensions = mutableListOf<C>()
return extensions.map { candidateFactory.createCandidate(it, ExplicitReceiverKind.EXTENSION_RECEIVER, extensionReceiver = explicitReceiver) } for (extensionCandidate in level.collectCandidates(explicitReceiver)) {
if (extensionCandidate.requiresExtensionReceiver) {
extensions.add(candidateFactory.createCandidate(extensionCandidate, ExplicitReceiverKind.EXTENSION_RECEIVER, extensionReceiver = explicitReceiver))
}
}
return extensions
} }
} }
@@ -85,9 +93,12 @@ private class QualifierScopeTowerProcessor<C: Candidate>(
override fun simpleProcess(data: TowerData): Collection<C> { override fun simpleProcess(data: TowerData): Collection<C> {
if (data != TowerData.Empty) return emptyList() if (data != TowerData.Empty) return emptyList()
val staticMembers = QualifierScopeTowerLevel(scopeTower, qualifier).collectCandidates(null) val staticMembers = mutableListOf<C>()
.filter { !it.requiresExtensionReceiver } for (towerCandidate in QualifierScopeTowerLevel(scopeTower, qualifier).collectCandidates(null)) {
.map { candidateFactory.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = null) } if (!towerCandidate.requiresExtensionReceiver) {
staticMembers.add(candidateFactory.createCandidate(towerCandidate, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = null))
}
}
return staticMembers return staticMembers
} }
} }
@@ -99,19 +110,21 @@ private class NoExplicitReceiverScopeTowerProcessor<C: Candidate>(
override fun simpleProcess(data: TowerData): Collection<C> override fun simpleProcess(data: TowerData): Collection<C>
= when(data) { = when(data) {
is TowerData.TowerLevel -> { is TowerData.TowerLevel -> {
data.level.collectCandidates(null).filter { !it.requiresExtensionReceiver }.map { val result = mutableListOf<C>()
candidateFactory.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = null) for (towerCandidate in data.level.collectCandidates(null)) {
if (!towerCandidate.requiresExtensionReceiver) {
result.add(candidateFactory.createCandidate(towerCandidate, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = null))
}
} }
result
} }
is TowerData.BothTowerLevelAndImplicitReceiver -> { is TowerData.BothTowerLevelAndImplicitReceiver -> {
val result = mutableListOf<C>() val result = mutableListOf<C>()
for (towerCandidate in data.level.collectCandidates(data.implicitReceiver)) {
data.level.collectCandidates(data.implicitReceiver).filter { it.requiresExtensionReceiver }.forEach { if (towerCandidate.requiresExtensionReceiver) {
result.add( result.add(candidateFactory.createCandidate(towerCandidate, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = data.implicitReceiver))
candidateFactory.createCandidate( }
it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = data.implicitReceiver))
} }
result result
} }
else -> emptyList() else -> emptyList()