Speed up JRuby + Rails startup time

first check – https://github.com/jruby/jruby/wiki/Improving-startup-time

Set JRUBY_OPTS for development

~/.rvm/hooks/after_use_jruby_opts
#!/usr/bin/env bash

. "${rvm_path}/scripts/functions/hooks/jruby"

export PROJECT_JRUBY_OPTS="-Xcompile.invokedynamic=false -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -J-noverify -Xcompile.mode=OFF"

if [[ "${rvm_ruby_string}" =~ "jruby" ]]
then
jruby_options_append "${PROJECT_JRUBY_OPTS[@]}"
else
jruby_options_remove "${PROJECT_JRUBY_OPTS[@]}"
jruby_clean_project_options
fi

One by one

-Xcompile.invokedynamic=false optimizations on bytecode instruction level dynamically.

-J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 same effect as client mode on 64bit JVM.

-J-noverify not verifying

-Xcompile.mode=OFF don’t do JIT

Nailgun

“Insanely Fast Java”
Preloads a JVM.

Not that much gain < 1 second

cd ~/.rvm/rubies/jruby-1.7.4/tool/nailgun
./configure
make install
$ time ruby bin/thor list
real 0m1.919s

$ ruby --ng-server &
NGServer started on all interfaces, port 2113.

$ time ruby --ng bin/thor list
real 0m1.331s

Drip

Charles Nutter @headius Nov 20 2012 “Big JRuby startup time improvements using Drip…give it a shot, let us know how it works: https://github.com/flatland/drip&#8221;

export JAVACMD=`which drip`
export DRIP_INIT_CLASS=org.jruby.main.DripMain

dripmain.rb
# org.jruby.main.DripMain
public static final String JRUBY_DRIP_PREBOOT_FILE = "./dripmain.rb";

Unfortunately buggy – https://github.com/flatland/drip/issues/51

All together

BEFORE LAZY REQUIRE (Bundler.require)
$ time ruby bin/rspec spec/models/tag_spec.rb
saved about ~3 secs.

DEFAULT
$ time ruby bin/rspec spec/models/tag_spec.rb

real 0m23.325s

JRUBY_OPTS

$ export JRUBY_OPTS="-Xcompile.invokedynamic=false -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -J-noverify -Xcompile.mode=OFF"
$ time ruby bin/rspec spec/models/tag_spec.rb

real 0m10.726s

JRUBY_OPTS + NAILGUN + SPORK

$ ruby --ng-server &
$ ruby --ng bin/spork
$ time ruby --ng bin/rspec spec/models/tag_spec.rb

real 0m3.453s

Auto enable Nailgun

~/.rvm/hooks/after_use_jruby

#!/usr/bin/env bash

\. "${rvm_path}/scripts/functions/hooks/jruby"

if [[ "${rvm_ruby_string}" =~ "jruby" ]]
then
jruby_ngserver_start
jruby_options_append "--ng" "${PROJECT_JRUBY_OPTS[@]}"
else
jruby_options_remove "--ng" "${PROJECT_JRUBY_OPTS[@]}"
jruby_clean_project_options
fi

Prefer binstub over bundle exec

bundle binstub rspec-core

bundle exec requires the executable script and call exec to replace the process. From the wiki “Avoid spawning sub-rubies”.