Skip to content

Commit 866f172

Browse files
committed
Faster base class sets
Speed up construction and testing of base class sets. Use a linear search with automatic bubbling up of hits.
1 parent fa1f23f commit 866f172

File tree

1 file changed

+40
-13
lines changed

1 file changed

+40
-13
lines changed

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,14 +1400,14 @@ object SymDenotations {
14001400
baseData._2
14011401

14021402
def computeBaseData(implicit onBehalf: BaseData, ctx: Context): (List[ClassSymbol], BaseClassSet) = {
1403-
val seen = mutable.SortedSet[Int]()
1403+
val seen = new BaseClassSetBuilder
14041404
def addBaseClasses(bcs: List[ClassSymbol], to: List[ClassSymbol])
14051405
: List[ClassSymbol] = bcs match {
14061406
case bc :: bcs1 =>
14071407
val bcs1added = addBaseClasses(bcs1, to)
1408-
if (seen contains bc.id) bcs1added
1408+
if (seen contains bc) bcs1added
14091409
else {
1410-
seen += bc.id
1410+
seen.add(bc)
14111411
bc :: bcs1added
14121412
}
14131413
case nil =>
@@ -1425,7 +1425,7 @@ object SymDenotations {
14251425
if (classParents.isEmpty && !emptyParentsExpected)
14261426
onBehalf.signalProvisional()
14271427
(classSymbol :: addParentBaseClasses(classParents, Nil),
1428-
new BaseClassSet(seen.toArray))
1428+
seen.result)
14291429
}
14301430

14311431
final override def derivesFrom(base: Symbol)(implicit ctx: Context): Boolean =
@@ -2073,17 +2073,44 @@ object SymDenotations {
20732073
}
20742074

20752075
class BaseClassSet(val classIds: Array[Int]) extends AnyVal {
2076-
def contains(sym: Symbol): Boolean = {
2076+
def contains(sym: Symbol, limit: Int) = {
20772077
val id = sym.id
2078-
var lo = 0
2079-
var hi = classIds.length - 1
2080-
while (lo <= hi) {
2081-
val mid = (lo + hi) / 2
2082-
if (id < classIds(mid)) hi = mid - 1
2083-
else if (id > classIds(mid)) lo = mid + 1
2084-
else return true
2078+
var i = 0
2079+
while (i < limit && classIds(i) != id) i += 1
2080+
i < limit && {
2081+
if (i > 0) {
2082+
val t = classIds(i)
2083+
classIds(i) = classIds(i - 1)
2084+
classIds(i - 1) = t
2085+
}
2086+
true
20852087
}
2086-
false
2088+
}
2089+
def contains(sym: Symbol): Boolean = contains(sym, classIds.length)
2090+
}
2091+
2092+
private class BaseClassSetBuilder {
2093+
private var classIds = new Array[Int](32)
2094+
private var length = 0
2095+
2096+
private def resize(size: Int) = {
2097+
val classIds1 = new Array[Int](size)
2098+
Array.copy(classIds, 0, classIds1, 0, classIds.length min size)
2099+
classIds = classIds1
2100+
}
2101+
2102+
def contains(sym: Symbol): Boolean =
2103+
new BaseClassSet(classIds).contains(sym, length)
2104+
2105+
def add(sym: Symbol): Unit = {
2106+
if (length == classIds.length) resize(length * 2)
2107+
classIds(length) = sym.id
2108+
length += 1
2109+
}
2110+
2111+
def result = {
2112+
if (length != classIds.length) resize(length)
2113+
new BaseClassSet(classIds)
20872114
}
20882115
}
20892116

0 commit comments

Comments
 (0)