This is an excerpt from the Scala Cookbook (partially modified for the internet). This is a short recipe, Recipe 14.13, “How to make your Scala shell scripts run faster by pre-compiling them.”
You love using Scala as a scripting language, but you’d like to eliminate the lag time in starting up a script.
-savecompiled argument of the Scala interpreter to save a compiled version of your script.
A basic Scala script like this:
#!/bin/sh exec scala "$0" "$@" !# println("Hello, world!") args foreach println
consistently runs with times like this on one of my computers:
real 0m1.573s user 0m0.574s sys 0m0.089s
Those times are pretty slow for a do-nothing script, so to improve this, add the
-savecompiled argument to the Scala interpreter line:
#!/bin/sh exec scala -savecompiled "$0" "$@" !# println("Hello, world!") args foreach println
Then run the script once. This will still run slow, but it generates a compiled version of the script. After that, the script runs with a consistently lower real time (wall clock) on all subsequent runs:
real 0m0.458s user 0m0.487s sys 0m0.075s
Precompiling your script shaves a nice chunk of time off the runtime of your script, even for a simple example like this.
When you run your script the first time, Scala generates a JAR file that matches the name of your script. For instance, I named my script test1.sh, and then ran it like this:
After running the script, I looked at the directory contents and saw that Scala created a file named test1.sh.jar. Scala creates this new file and also leaves your original script in place.
On subsequent runs, the Scala interpreter sees that there’s a JAR file associated with the script, and if the script hasn’t been modified since the JAR file was created, it runs the precompiled code from the JAR file instead of the source code in the script. This results in a faster runtime because the source code doesn’t need to be compiled.
As an interesting note about how this works, you can look at the contents of the JAR file using the
$ jar tvf test1.sh.jar 43 Wed Jul 25 15:44:26 MDT 2012 META-INF/MANIFEST.MF 965 Wed Jul 25 15:44:26 MDT 2012 Main$$anon$1$$anonfun$1.class 725 Wed Jul 25 15:44:26 MDT 2012 Main$$anon$1.class 557 Wed Jul 25 15:44:26 MDT 2012 Main$.class 646 Wed Jul 25 15:44:26 MDT 2012 Main.class
In this example, I didn’t include a
main method in an
object or use the
App trait with an
object, so Scala assumed the name
Main for the main/primary object that it created to run my script.
|this post is sponsored by my books:|
#1 New Release
FP Best Seller
Learn Scala 3
Learn FP Fast