summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2011-04-19 10:56:58 +0000
committerMartin Odersky <odersky@gmail.com>2011-04-19 10:56:58 +0000
commit52fbbcc82470e100d95ac9cdb468060620f1e29e (patch)
treef28a75ddc76f61cb180d8a37d21d7f623d8ec581
parentb7bdf048b1feb39b3e4f30cabfbc49a2cb535d28 (diff)
downloadscala-52fbbcc82470e100d95ac9cdb468060620f1e29e.tar.gz
scala-52fbbcc82470e100d95ac9cdb468060620f1e29e.tar.bz2
scala-52fbbcc82470e100d95ac9cdb468060620f1e29e.zip
Further optimizations of implicits.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala17
-rw-r--r--src/compiler/scala/tools/nsc/util/Statistics.scala2
2 files changed, 16 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 647bbd01ab..a05aefe1fa 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -13,7 +13,7 @@ package typechecker
import annotation.tailrec
import scala.collection.{ mutable, immutable }
-import mutable.{ LinkedHashMap, ListBuffer }
+import mutable.{ HashMap, LinkedHashMap, ListBuffer }
import scala.util.matching.Regex
import symtab.Flags._
import util.Statistics._
@@ -71,10 +71,12 @@ trait Implicits {
private type InfoMap = LinkedHashMap[Symbol, List[ImplicitInfo]]
private val implicitsCache = new LinkedHashMap[Type, Infoss]
private val infoMapCache = new LinkedHashMap[Symbol, InfoMap]
+ private val improvesCache = new HashMap[(ImplicitInfo, ImplicitInfo), Boolean]
def resetImplicits() {
implicitsCache.clear()
infoMapCache.clear()
+ improvesCache.clear()
}
private val ManifestSymbols = Set(PartialManifestClass, FullManifestClass, OptManifestClass)
@@ -229,8 +231,17 @@ trait Implicits {
def improves(info1: ImplicitInfo, info2: ImplicitInfo) = {
incCounter(improvesCount)
(info2 == NoImplicitInfo) ||
- (info1 != NoImplicitInfo) &&
- isStrictlyMoreSpecific(info1.tpe, info2.tpe, info1.sym, info2.sym)
+ (info1 != NoImplicitInfo) && {
+ if (info1.sym.isStatic && info2.sym.isStatic) {
+ improvesCache get (info1, info2) match {
+ case Some(b) => incCounter(improvesCachedCount); b
+ case None =>
+ val result = isStrictlyMoreSpecific(info1.tpe, info2.tpe, info1.sym, info2.sym)
+ improvesCache((info1, info2)) = result
+ result
+ }
+ } else isStrictlyMoreSpecific(info1.tpe, info2.tpe, info1.sym, info2.sym)
+ }
}
/** Map all type params in given list to WildcardType
diff --git a/src/compiler/scala/tools/nsc/util/Statistics.scala b/src/compiler/scala/tools/nsc/util/Statistics.scala
index 86b9ca5cda..b6e61a4014 100644
--- a/src/compiler/scala/tools/nsc/util/Statistics.scala
+++ b/src/compiler/scala/tools/nsc/util/Statistics.scala
@@ -159,6 +159,7 @@ object Statistics {
val implicitCacheHits = new Counter
val implicitCacheMisses = new Counter
val improvesCount = new Counter
+ val improvesCachedCount = new Counter
val subtypeAppInfos = new SubCounter(subtypeCount)
val subtypeImprovCount = new SubCounter(subtypeCount)
val subtypeETNanos = new Timer
@@ -260,6 +261,7 @@ abstract class Statistics {
inform("#implicit searches : " + implicitSearchCount)
inform("#tried, plausible, matching, typed, found implicits: "+triedImplicits+", "+plausiblyCompatibleImplicits+", "+matchingImplicits+", "+typedImplicits+", "+foundImplicits)
inform("#implicit improves tests : " + improvesCount)
+ inform("#implicit improves cached: " + improvesCachedCount)
inform("#implicit inscope hits : " + inscopeImplicitHits)
inform("#implicit oftype hits : " + oftypeImplicitHits)
}