Mike McFarland
Mike McFarland

Reputation: 657

Achieve SBT Run startup speed while executing through command line

I've been working on a small set of command line programs in Scala. While developing I used SBT, and tested the program with run within the console. At this point the programs had a fast startup time (when re-run after initial compilation); nearly instant, even with additional dependencies.

Now that I'm trying to actually utilize them on my system outside of sbt, the speeds have noticeable lag. I'm looking for ways to reduce this, since the nature of these utilities requires little to no delay.

The best speeds I've achieved so far has been through utilizing Drip. I include all dependencies in a lib directory by utilizing Pack and then run by executing a shell script like this:

#!/bin/sh

SCRIPT=$(readlink -f "$0")
SCRIPT_PATH=$(dirname "$SCRIPT")
PROG_HOME=`cd "$SCRIPT_PATH/../" && pwd`


CLASSPATH_SUFFIX=""
# Path separator used in EXTRA_CLASSPATH
PSEP=":"
exec drip \
     -cp "${PROG_HOME}/lib/*${CLASSPATH_SUFFIX}" \ # Add lib directory to classpath
     TagWorkspace "$@"  # TagWorkspace is the main class

This is still noticeably slower then invoking run from within SBT. I'm curious as to why SBT is able to startup the application so much faster, and if there is someway for me to levarage its strategy, or SBT itself, even if that means keeping a long living process around to actually run a command through.

Upvotes: 2

Views: 955

Answers (2)

Nicolas
Nicolas

Reputation: 2321

The only slowness I have is launching SBT. Running a hello-word Scala app with java (no Drip) version 1.8 on a 7381 bogomips CPU takes only 0.2 seconds.

If you're not in that magnitude, I suspect your application startup requires loading thousands of classes, and creating instances of them.

Upvotes: 0

dpratt
dpratt

Reputation: 364

Unless you have forking turned on for your run task, this is likely due to VM startup time. When you run from inside an active SBT session, you have an already initialized VM pointing at your classes - all SBT needs to do is create a new ClassLoader and point it at your build output directory. This bypasses all of the other (not insignificant) stuff that happens when you fire up a new VM.

Have you tried using the client VM to start your utility from the command line? Sadly, this isn't an option with 64-bit Java, since Oracle apparently doesn't want to support it, but if you're using a 32-bit VM, try adding the -client argument to the list that you give the VM from the command line.

If you are using a 64-bit VM, some googling will find you some unofficial forks of OpenJDK that have the client VM re-enabled. It's really just a #define in the JVM build itself - it works fine once it's been compiled in.

Upvotes: 1

Related Questions