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> {
val members =
MemberScopeTowerLevel(scopeTower, explicitReceiver)
.collectCandidates(null).filter { !it.requiresExtensionReceiver }
return members.map { candidateFactory.createCandidate(it, ExplicitReceiverKind.DISPATCH_RECEIVER, extensionReceiver = null) }
val members = mutableListOf<C>()
for (memberCandidate in MemberScopeTowerLevel(scopeTower, explicitReceiver).collectCandidates(null)) {
if (!memberCandidate.requiresExtensionReceiver) {
members.add(candidateFactory.createCandidate(memberCandidate, ExplicitReceiverKind.DISPATCH_RECEIVER, extensionReceiver = null))
}
}
return members
}
private fun resolveAsExtension(level: ScopeTowerLevel): Collection<C> {
val extensions = level.collectCandidates(explicitReceiver).filter { it.requiresExtensionReceiver }
return extensions.map { candidateFactory.createCandidate(it, ExplicitReceiverKind.EXTENSION_RECEIVER, extensionReceiver = explicitReceiver) }
val extensions = mutableListOf<C>()
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> {
if (data != TowerData.Empty) return emptyList()
val staticMembers = QualifierScopeTowerLevel(scopeTower, qualifier).collectCandidates(null)
.filter { !it.requiresExtensionReceiver }
.map { candidateFactory.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = null) }
val staticMembers = mutableListOf<C>()
for (towerCandidate in QualifierScopeTowerLevel(scopeTower, qualifier).collectCandidates(null)) {
if (!towerCandidate.requiresExtensionReceiver) {
staticMembers.add(candidateFactory.createCandidate(towerCandidate, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = null))
}
}
return staticMembers
}
}
@@ -99,19 +110,21 @@ private class NoExplicitReceiverScopeTowerProcessor<C: Candidate>(
override fun simpleProcess(data: TowerData): Collection<C>
= when(data) {
is TowerData.TowerLevel -> {
data.level.collectCandidates(null).filter { !it.requiresExtensionReceiver }.map {
candidateFactory.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = null)
val result = mutableListOf<C>()
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 -> {
val result = mutableListOf<C>()
data.level.collectCandidates(data.implicitReceiver).filter { it.requiresExtensionReceiver }.forEach {
result.add(
candidateFactory.createCandidate(
it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = data.implicitReceiver))
for (towerCandidate in data.level.collectCandidates(data.implicitReceiver)) {
if (towerCandidate.requiresExtensionReceiver) {
result.add(candidateFactory.createCandidate(towerCandidate, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = data.implicitReceiver))
}
}
result
}
else -> emptyList()