Since the proliferation of Bundler, we’ve had multiple options for
how to invoke Ruby executables; each option has its own set of
advantages & disadvantages. The easiest form of invocation is to use
the executable that is installed when the gem is installed; things like:
rails
, rake
, or rspec
. But, this form of invocation suffers from
the problem of potentially loading a version of a gem that differs from
the version your project bundle requires; you know you’ve run into this
problem when you see a message like the following:
You have already activated <gem-name> <version-x> but your Gemfile requires <gem-name> <version-y>. Consider using bundle exec.
Binstubs
To get around the above problem, we often prefix our executables with
bundle exec
; and, while this works, I’ve often felt that the execution
time was noticeably slower. But, Bundler provides another solution to this
problem: binstubs. I don’t think this option is as well known as
bundle exec
, but this is how you create them:
$ bundle install --binstubs
Or:
$ bundle config bin bin
$ bundle install
Both of the above options will install all the executables that are
provided by your bundle in the bin
directory, you can then invoke one
of the executables like this: ./bin/rspec
.
RSpec executable benchmarks
I was interested in benchmarking the various options, to see how they
actually stack up to each other; I also wanted to see how
funny-falcon’s performance patches
affected the execution time – which you’ll see in the 1.9.3-p194-perf
column. I have a separate post with instructions on how to install
these patches. So, first off, I wanted to benchmark
executing rspec
1 – all the times are listed in seconds
2:
Command | 1.9.3-p194 | 1.9.3-p194-perf |
---|---|---|
rspec |
0.27 | 0.22 |
./bin/rspec |
0.49 | 0.40 |
bundle exec rspec |
0.98 | 0.75 |
So, my plan going forward for executables like rspec
: use the regular
gem executable. If I run into a version conflict, hopefully I can fix
the issue by upgrading the gem in the appropriate projects; if that is
not an option, then at that point I’ll switch to binstubs for the
effected projects.
Rails executable benchmarks
Just running rspec
does not necessarily load your whole Rails
application. So, the following table shows invoking rails runner ''
3, to see what impact that has on run times.
Command | 1.9.3-p194 | 1.9.3-p194-perf |
---|---|---|
./script/rails |
1.10 | 0.83 |
rails |
1.27 | 0.95 |
./bin/rails |
1.53 | 1.11 |
bundle exec rails |
2.01 | 1.47 |
I showed all the options for comparison’s sake, but I actually don’t
think there’s any reason not to use ./script/rails
; and, luckily my
Rails command shortcuts take care of that for
me.