How to reduce Scala (/ Java) startup overhead?
Asked Answered
E

3

23

I'm pretty ignorant of the Java world (I do mostly C / Python) but Scala looked interesting enough to pull me in. One problem I'm having with it is the enormous startup overhead - 0.3 seconds minimum, much more if I'm using the interpreter instead of compiling, compared to effectively 0 for Python or C. So even though the language is tens of times faster than Python once it gets going, if I'm trying to use it for simple tasks it's still considerably slower in practice.

Is there any way to reduce this time, or is it an unavoidable part of the JVM + the number of required (implicit) imports for a Scala program?

Excogitate answered 22/8, 2009 at 14:10 Comment(1)
See also #1491825Paradiddle
C
15

What sort of computer are you using it on? Obviously there is a JVM startup overhead but this is even greater if the JVM detects you are running on a server-class machine.

In the J2SE platform version 5.0 a class of machine referred to as a server-class machine has been defined as a machine with:

  • 2 or more physical processors
  • 2 or more Gbytes of physical memory

You can put the JVM in client mode by using the -client option. The client mode is tuned for fast startup time.

There is also the move to modularize the JVM (project Jigsaw) which will improve startup times even more - this has started with JDK 1.6.0_10.

Cestus answered 22/8, 2009 at 15:50 Comment(1)
Thanks. -client helps significantly, bringing my 'echo' test program from 0.3s to 0.12 seconds average. That's low enough to feel responsive in most cases. Too bad most 'clients' are now thick enough to meet the server requirements.Excogitate
D
8

See Nailgun

Dimmer answered 22/8, 2009 at 14:11 Comment(0)
G
8

You could work around the JVM start-up time by opening the Scala REPL and then loading your scripts directly into it using the :load command. This compiles (it does take some time, but I don't find it long in practice) the contents of the script and loads it for use in the REPL. For example:


scala> :load testScript.scala
Loading testScript.scala...
import scala.collection.mutable.Map
memory: scala.collection.mutable.Map[Int,Int] = Map()
fib: (Int)Int
res7: Int = 165580141

scala> fib(10)
res1: Int = 55

scala> fib(11)
res2: Int = 89

scala> fib(12)
res3: Int = 144

scala> fib(13)
res4: Int = 233

For example, a typical workflow of mine when writing different prototypes in Scala is as follows. I have a text editor open in one window, and the Scala REPL in another. I write my code and then load it (:load script.scala). The results produced by the script are immediately available (as seen in the above transcript, res7) and any functions, classes or objects defined in the script are also available. And it's faster than running scala myScript.scala as the JVM is already loaded.

If you go the compiled route, use fsc (the fast Scala compiler). The first time it's invoked it creates a daemon process that compiles the code. Therefore you will only have to pay the JVM start-up price once. Just note that if you change the value of CLASSPATH (the environment variable), you'll have to restart fsc (it's something that has bugged me for a while).

-- Flaviu Cipcigan

Gabor answered 22/8, 2009 at 17:59 Comment(1)
Even with fsc there is no way to bring compilation down to a sane (i.e. tool-friendly) startup time. The goal is to reduce startup time once I've compiled it, which is still onerously long.Excogitate

© 2022 - 2024 — McMap. All rights reserved.