RSpec load time incredible long on OS X

2020-06-06 06:48发布

问题:

We use Mongodb and RSpec for our project. On my OS X machine RSpec for a single controller runs in:

Finished in 0.24996 seconds (files took 25.39 seconds to load)

on the other hand my friend has Ubuntu and for him the same spec runs in:

Finished in 0.27996 seconds (files took 4.05 seconds to load)

Loading time is more than 6 times longer on my machine. What could be the reason?

P.S. Not using OS X is not a solution :/

Update:

More information about our setup:

We both use ruby 2.2. We run specs via guardfile with cmd: bundle exec rspec

My friend uses rbenv and which rspec returns

"/home/dan/.rbenv/shims/rspec`

I use rvm and which rspec returns:

$ which rspec
rspec: aliased to bundled_rspec
$ which bundled_rspec
bundled_rspec () {
    _run-with-bundler rspec $@

Update 2:

I just cloned https://github.com/eliotsykes/rspec-rails-examples and ran rspec. It took over 36s to load files. So it is not mongodb related. I just noticed that rails server is also loading very long.

> time rspec -v
3.3.2

real    0m2.539s
user    0m1.067s
sys 0m0.185s

回答1:

Bundler

Looks like some bundler loading issue for me. I'd recommend to make some more measurements. Do you use 1 gemset per project or store everything in 1 gemset (it's true if you don't use any)? If you have lots of gems in 1 directory (i.e. 1 gemset for all) it will eventually slows down bundler a lot, since it needs to traverse more paths to make its job.

bundle | wc -l # how many gems bundler uses in your current project
gem list -q | wc -l # how many gems in your gemset 

If gem list -q | wc -l reports quite large value (I have 237 and everything seems normal for me), maybe you need to split installed gems into a separate gemset per project.

Make some more measurements with time command, look for the real value, it's total sum.

First, remove your bundled_rspec wrapper, it's not needed with latest RVM versions.

Then measure your rspec loading with and without Bundler:

time rspec -v # with implicit bundler loading, rubygems-bundler gem is in use
time NOEXEC_DISABLE=1 rspec -v # without bundler, disable rubygems-bundler gem for this call`

If time rspec -v gives you big numbers even for project with relatively small Gemfile, it's a bundler issue.

Rails

Next bottleneck is usually Rails itself. Try measuring one test that doesn't load Rails (i.e. just spec_helper) and then test with rails (i.e. with rails_helper).

As soon you start seeing big difference in numbers, you'll know where you have a problem.

Spring

As a quick-fix solution to improve rails performance is a usage of spring gem. If you use Rails 4.1+ Spring is already enabled.

To enable Spring for rspec add to your Gemfile

gem 'spring-commands-rspec', group: :development

and run

$ bundle install
$ spring binstub --all

Last command will generate wrappers for all spring supported binaries in your project's bin folder (take a look there and don't forget to commit them). After that you should run rspec with bin/rspec. First run will be still slow, but all consequent runs should be fast enough since Rails will be already loaded.