From d905558749cceff50e9872efb490450c54b6bd81 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 13 Jul 2012 18:24:37 +0200 Subject: Variation #10 to optimze findMember Undoing the memberType caching. This seems to make it slower rather than faster. Also, comparing new vs old statistics shows that only very few asSeenFrom operations are saved by the caching. --- src/compiler/scala/tools/nsc/MainBench.scala | 48 ++++++++++++++++++++ src/reflect/scala/reflect/internal/StdNames.scala | 2 +- src/reflect/scala/reflect/internal/Types.scala | 54 +++-------------------- 3 files changed, 55 insertions(+), 49 deletions(-) create mode 100644 src/compiler/scala/tools/nsc/MainBench.scala diff --git a/src/compiler/scala/tools/nsc/MainBench.scala b/src/compiler/scala/tools/nsc/MainBench.scala new file mode 100644 index 0000000000..0037de7b94 --- /dev/null +++ b/src/compiler/scala/tools/nsc/MainBench.scala @@ -0,0 +1,48 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.tools.nsc + +import java.io.File +import File.pathSeparator + +import scala.tools.nsc.interactive.{ RefinedBuildManager, SimpleBuildManager } +import scala.tools.nsc.io.AbstractFile +import scala.tools.nsc.reporters.{Reporter, ConsoleReporter} +import scala.reflect.internal.util.{ BatchSourceFile, FakePos } //{Position} +import Properties.{ versionString, copyrightString, residentPromptString, msilLibPath } +import scala.reflect.internal.util.Statistics + +/** The main class for NSC, a compiler for the programming + * language Scala. + */ +object MainBench extends Driver with EvalLoop { + + lazy val theCompiler = Global(settings, reporter) + + override def newCompiler() = theCompiler + + val NIter = 50 + val NBest = 10 + + override def main(args: Array[String]) = { + val times = new Array[Long](NIter) + var start = System.nanoTime() + for (i <- 0 until NIter) { + if (i == NIter-1) { + theCompiler.settings.Ystatistics.value = true + Statistics.enabled = true + } + process(args) + val end = System.nanoTime() + val duration = (end-start)/1000000 + println(s"${duration}ms") + times(i) = duration + start = end + } + val avg = times.sorted.take(NBest).sum / NBest + println(s"avg shortest $NBest times ${avg}ms") + } +} diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index b9230dc97b..376abd6a38 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -294,7 +294,7 @@ trait StdNames { val WHILE_PREFIX = "while$" // Compiler internal names - val ANYname: NameType = "" + val ANYname: NameType = "" val CONSTRUCTOR: NameType = "" val EQEQ_LOCAL_VAR: NameType = "eqEqTemp$" val FAKE_LOCAL_THIS: NameType = "this$" diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index baa5a97f83..399b1a039a 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -1032,21 +1032,10 @@ trait Types extends api.Types { self: SymbolTable => //Console.println("find member " + name.decode + " in " + this + ":" + this.baseClasses)//DEBUG var members: Scope = null - var membertpes: mutable.Map[Symbol, Type] = null var required = requiredFlags var excluded = excludedFlags | DEFERRED var continue = true var self: Type = null - - def getMtpe(cache: mutable.Map[Symbol, Type], sym: Symbol): Type = cache get sym match { - case Some(tpe) if tpe ne null => - tpe - case _ => - val result = self memberType sym - cache(sym) = result - result - } - while (continue) { continue = false val bcs0 = baseClasses @@ -1064,10 +1053,7 @@ trait Types extends api.Types { self: SymbolTable => (bcs eq bcs0) || (flags & PrivateLocal) != PrivateLocal || (bcs0.head.hasTransOwner(bcs.head)))) { - if (members eq null) { - members = newScope - membertpes = new mutable.HashMap - } + if (members eq null) members = newScope var others: ScopeEntry = members.lookupEntry(sym.name) var symtpe: Type = null while ((others ne null) && { @@ -1077,7 +1063,7 @@ trait Types extends api.Types { self: SymbolTable => (flags & PRIVATE) != 0 || { if (self eq null) self = this.narrow if (symtpe eq null) symtpe = self.memberType(sym) - !(getMtpe(membertpes, other) matches symtpe) + !(self.memberType(other) matches symtpe) })}) { others = members lookupNextEntry others } @@ -1092,7 +1078,7 @@ trait Types extends api.Types { self: SymbolTable => bcs = bcs.tail } // while (!bcs.isEmpty) required |= DEFERRED - excluded = excludedFlags + excluded &= ~(DEFERRED.toLong) } // while (continue) Statistics.popTimer(typeOpsStack, start) if (suspension ne null) suspension foreach (_.suspended = false) @@ -1125,32 +1111,12 @@ trait Types extends api.Types { self: SymbolTable => var members: List[Symbol] = null var lastM: ::[Symbol] = null var membertpe: Type = null - var membertpes: Array[Type] = null var required = requiredFlags var excluded = excludedFlags | DEFERRED var continue = true var self: Type = null val fingerPrint: Long = name.fingerPrint - def getMtpe(idx: Int, sym: Symbol): Type = { - var result = membertpes(idx) - if (result eq null) { - result = self memberType sym - membertpes(idx) = result - } - result - } - - def addMtpe(xs: Array[Type], idx: Int, tpe: Type): Array[Type] = - if (idx < xs.length) { - xs(idx) = tpe - xs - } else { - val ys = new Array[Type](xs.length * 2) - Array.copy(xs, 0, ys, 0, xs.length) - addMtpe(ys, idx, tpe) - } - while (continue) { continue = false val bcs0 = baseClasses @@ -1176,24 +1142,18 @@ trait Types extends api.Types { self: SymbolTable => } else if (member eq NoSymbol) { member = sym } else if (members eq null) { - var symtpe: Type = null if ((member ne sym) && ((member.owner eq sym.owner) || (flags & PRIVATE) != 0 || { if (self eq null) self = this.narrow if (membertpe eq null) membertpe = self.memberType(member) - symtpe = self.memberType(sym) - !(membertpe matches symtpe) + !(membertpe matches self.memberType(sym)) })) { lastM = new ::(sym, null) members = member :: lastM - membertpes = new Array[Type](8) - membertpes(0) = membertpe - membertpes(1) = symtpe } } else { var others: List[Symbol] = members - var idx = 0 var symtpe: Type = null while ((others ne null) && { val other = others.head @@ -1202,16 +1162,14 @@ trait Types extends api.Types { self: SymbolTable => (flags & PRIVATE) != 0 || { if (self eq null) self = this.narrow if (symtpe eq null) symtpe = self.memberType(sym) - !(getMtpe(idx, other) matches symtpe) + !(self.memberType(other) matches symtpe) })}) { others = others.tail - idx += 1 } if (others eq null) { val lastM1 = new ::(sym, null) lastM.tl = lastM1 lastM = lastM1 - membertpes = addMtpe(membertpes, idx, symtpe) } } } else if (excl == DEFERRED) { @@ -1225,7 +1183,7 @@ trait Types extends api.Types { self: SymbolTable => bcs = if (name == nme.CONSTRUCTOR) Nil else bcs.tail } // while (!bcs.isEmpty) required |= DEFERRED - excluded = excludedFlags + excluded &= ~(DEFERRED.toLong) } // while (continue) Statistics.popTimer(typeOpsStack, start) if (suspension ne null) suspension foreach (_.suspended = false) -- cgit v1.2.3