diff options
author | mpociecha <michal.pociecha@gmail.com> | 2014-12-01 00:11:21 +0100 |
---|---|---|
committer | mpociecha <michal.pociecha@gmail.com> | 2014-12-05 01:21:05 +0100 |
commit | 959d1344b71c9eca1fb60c618d2bc1a4382e250e (patch) | |
tree | 52c6032fc46e8a6a3267766417d5b1b6e14255fe /src | |
parent | a8c43dc5caf7439dbcb47f6c25b33fb6b3ed8705 (diff) | |
download | scala-959d1344b71c9eca1fb60c618d2bc1a4382e250e.tar.gz scala-959d1344b71c9eca1fb60c618d2bc1a4382e250e.tar.bz2 scala-959d1344b71c9eca1fb60c618d2bc1a4382e250e.zip |
Add benchmarks to compare recursive and flat cp representations
The goal of these changes is to add possibility to:
- compare an efficiency and a content of both cp implementations
(ClassPathImplComparator)
- examine the memory consumption by creating a lot of globals using
a specified classpath (ClassPathMemoryConsumptionTester) - it can be
considered as e.g. some approximation of ScalaPresentationCompilers
in Scala IDE when working with many projects
ClassPathMemoryConsumptionTester is placed in main (I mean not test)
sources so thanks to that it has properly, out of the box configured
boot classpath etc. and it's easy to use it, e.g.:
scala scala.tools.nsc.ClassPathMemoryConsumptionTester
-YclasspathImpl:<implementation_to_test> -cp <some_cp>
-sourcepath <some_sp> -requiredInstances 50 SomeFileToCompile.scala
At the end it waits for the "exit" command so there can be used some
profiler like JProfiler to look how the given implementation behaves.
Also flat classpath implementation is set as a default one to test it
on Jenkins. This particular change must be reverted when all tests
will pass because for now it's not desirable to make it permanently
the default representation.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/ClassPathMemoryConsumptionTester.scala | 77 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/settings/ScalaSettings.scala | 2 |
2 files changed, 78 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/ClassPathMemoryConsumptionTester.scala b/src/compiler/scala/tools/nsc/ClassPathMemoryConsumptionTester.scala new file mode 100644 index 0000000000..2faf6c6272 --- /dev/null +++ b/src/compiler/scala/tools/nsc/ClassPathMemoryConsumptionTester.scala @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014 Contributor. All rights reserved. + */ +package scala.tools.nsc + +import scala.io.StdIn.readLine + +/** + * Simple application to check out amount of memory used by chosen classpath representation. + * It allows us to create many scalac-like calls based on specified parameters, where each main retains Global. + * And we need additional tool (e.g. profiler) to measure memory consumption itself. + */ +object ClassPathMemoryConsumptionTester { + + private class TestSettings extends Settings { + val requiredInstances = IntSetting("-requiredInstances", + "Determine how many times classpath should be loaded", 10, Some((1, 10000)), (_: String) => None) + } + + private class MainRetainsGlobal extends scala.tools.nsc.MainClass { + var retainedGlobal: Global = _ + override def doCompile(compiler: Global) { + retainedGlobal = compiler + super.doCompile(compiler) + } + } + + def main(args: Array[String]): Unit = { + if (args contains "-help") usage() + else doTest(args) + } + + private def doTest(args: Array[String]) = { + val settings = loadSettings(args.toList) + + val mains = (1 to settings.requiredInstances.value) map (_ => new MainRetainsGlobal) + + // we need original settings without additional params to be able to use them later + val baseArgs = argsWithoutRequiredInstances(args) + + println(s"Loading classpath ${settings.requiredInstances.value} times") + val startTime = System.currentTimeMillis() + + mains map (_.process(baseArgs)) + + val elapsed = System.currentTimeMillis() - startTime + println(s"Operation finished - elapsed $elapsed ms") + println("Memory consumption can be now measured") + + var textFromStdIn = "" + while (textFromStdIn.toLowerCase != "exit") + textFromStdIn = readLine("Type 'exit' to close application: ") + } + + /** + * Prints usage information + */ + private def usage(): Unit = + println( """Use classpath and sourcepath options like in the case of e.g. 'scala' command. + | There's also one additional option: + | -requiredInstances <int value> Determine how many times classpath should be loaded + """.stripMargin.trim) + + private def loadSettings(args: List[String]) = { + val settings = new TestSettings() + settings.processArguments(args, processAll = true) + if (settings.classpath.isDefault) + settings.classpath.value = sys.props("java.class.path") + settings + } + + private def argsWithoutRequiredInstances(args: Array[String]) = { + val instancesIndex = args.indexOf("-requiredInstances") + if (instancesIndex == -1) args + else args.dropRight(args.length - instancesIndex) ++ args.drop(instancesIndex + 2) + } +} diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 18e639b81c..c599b7b443 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -202,7 +202,7 @@ trait ScalaSettings extends AbsScalaSettings val YmethodInfer = BooleanSetting ("-Yinfer-argument-types", "Infer types for arguments of overriden methods.") val etaExpandKeepsStar = BooleanSetting ("-Yeta-expand-keeps-star", "Eta-expand varargs methods to T* rather than Seq[T]. This is a temporary option to ease transition.").withDeprecationMessage(removalIn212) val inferByName = BooleanSetting ("-Yinfer-by-name", "Allow inference of by-name types. This is a temporary option to ease transition. See SI-7899.").withDeprecationMessage(removalIn212) - val YclasspathImpl = ChoiceSetting ("-YclasspathImpl", "implementation", "Choose classpath scanning method.", List(ClassPathRepresentationType.Recursive, ClassPathRepresentationType.Flat), ClassPathRepresentationType.Recursive) + val YclasspathImpl = ChoiceSetting ("-YclasspathImpl", "implementation", "Choose classpath scanning method.", List(ClassPathRepresentationType.Recursive, ClassPathRepresentationType.Flat), ClassPathRepresentationType.Flat) val YdisableFlatCpCaching = BooleanSetting ("-YdisableFlatCpCaching", "Do not cache flat classpath representation of classpath elements from jars across compiler instances.") val YvirtClasses = false // too embryonic to even expose as a -Y //BooleanSetting ("-Yvirtual-classes", "Support virtual classes") |