How to diagnose slow rails / rake / rspec tasks - ruby-on-rails

I always have a significant delay (c.10 seconds) when running tasks like:
rails server
rake assets:precompile
rspec spec
The delay is at the point before it says:
Connecting to database specified by database.yml
I've found several articles identifying 10 or more different parameters that can be tuned to speed up rake and / or rspec runs. But I'm reluctant to start fiddling around with 10 different parameters without a better understanding of what's causing it.
Is there way to diagnose what's causing that delay? Like something more verbose?
Supplementary info:
Ubuntu 14
Ruby 1.9.3
Rails 3.2

Thanks to #MaxWilliams for the link to this post How do I debug a slow rails app boot time?
I started using Mark Ellul's Bumbler - http://github.com/mark-ellul/Bumbler
It gave me exactly what I wanted - an insight into what's going in the background and which gems are taking the time. Of course I still need to speed up the slow ones (fog and authlogic seem to be two of the main culprits). But that's at different question.

Related

Rails - Mongoid : Slow problem between production and development

I have a problem on my Rails application.
I am in version 3.2.22 of rails and 2.2.5 of ruby connect to a mongodb 2.6.
The problem is that I have huge difference in performance on simple or even more complex queries.
For example :
I run rails c development and then I execute my function (quite complex) it responds after 30 seconds
I run rails c production, I perform the same function as the previous one, it responds after 6 minutes 30 seconds, 7 times slower.
So I try to copy pasted the configuration 'development' in 'production', but the result remains the same, same for the Gemfile.
I look in all the code of the project no difference between the environment production and development.
Do you know the differences in the heart of rails between these two environments? did anyone ever encounter the problem?
Importantly, I am of course connecting to the same database.
Thanks in advance.
You have not specified your mongo (Ruby driver) and mongoid versions, if they are old you may need to upgrade and/or adjust the code to your environment.
To determine whether the slowdown happens in the database or in your application, use command monitoring as described here: https://docs.mongodb.com/ruby-driver/current/tutorials/ruby-driver-monitoring/#command-monitoring
Look at the log entries corresponding to your queries and make note of how log they take in each environment. By implementing a custom event subscriber you can also save the commands being sent and verify that they are identical between the two environments.
I got this!
When I saw the number of requests in production, I immediately thought of the query cache.
I found the 'identity_map_enabled' parameter for mongo, so I changed it to true, and hop magic!

Improve slow Rails startup time (rails console, rails server)

I work with several Rails apps, some on Rails 3.2/Ruby 2.0, and some one Rails 2.3/Ruby 1.8.7.
What they have in common is that, as they've grown and added more dependencies/gems, they take longer and longer to start. Development, Test, Production, console, it doesn't matter; some take 60+ seconds.
What is the preferred way to first, profile for what is causing load times to be so slow, and two, improve the load times?
There are a few things that can cause this.
Too many GC passes and general VM shortcomings - See this answer for a comprehensive explanation. Ruby <2.0 has some really slow bits that can dramatically increase load speeds; compiling Ruby with the Falcon or railsexpress patches can massively help that. All versions of MRI Ruby use GC settings by default that are inappropriate for Rails apps.
Many legacy gems that have to be iterated over in order to load files. If you're using bundler, try bundle clean. If you're using RVM, you could try creating a fresh gemset.
As far as profiling goes, you can use ruby-prof to profile what happens when you boot your app. You can wrap config/environment.rb in a ruby-prof block, then use that to generate profile reports of a boot cycle with something like rails r ''. This can help you track down where you're spending the bulk of your time in boot. You can profile individual sections, too, like the bundler setup in boot.rb, or the #initialize! call in environment.rb.
Something you might not be considering is DNS timeouts. If your app is performing DNS lookups on boot, which it is unable to resolve, these can block the process for $timeout seconds (which might be as high as 30 in some cases!). You might audit the app for those, as well.
Ryan has a good tutorial about speeding up tests, console, rake tasks: http://railscasts.com/episodes/412-fast-rails-commands?view=asciicast
I have checked every methods there and found "spring" the best. Just run the tasks like:
$ spring rspec
The time for your first run of spring will be same as before, but the second and later will be much faster.
Also, from my experience, there will be time you need to stop spring server and restart when there is weird error, but the chance is rare.
For ruby 2 apps, try zeus - https://github.com/burke/zeus
1.8 apps seem to boot much faster than 1.9, spork might help? http://railscasts.com/episodes/285-spork

Heroku App Boot Timeout

I've got a rather large, 2.3 upgraded to Rails 3 application, that's fat enough it's not making it through the 60 second startup door at Heroku, and therefore it's crashing. I've done a bunch of work to minimize load times within Gems and initializers, but there's some random process that's burning time and I'm not exactly sure what it is. I could use another set of eyes.
Here's a GIST with the config.ru, application.rb, and environment.rb and the Gemfile.
https://gist.github.com/2026140
Any thoughts would be greatly appreciated.
This was due, at least in my case, to two things: 1) a lot of gems, and 2) Mongo taking a long time to initialize (big burdened database).
To fix the gems, on my local dev, I patched bundler Kernel#require statement so I could see which were taking the longest to load. Then, I tried to remove them. Barring that, I set them to :require => false and manually required them where they were needed.
Secondly, I monkey patched Mongoid so that it doesn't try to connect to the database when the app is starting. This helped dramatically with the slow boot time (removed over 10 seconds).
Heroku's boot timeout bit me too. I read several blog posts about how to get around it and ended up automating some of the solutions into a gem.
To reduce the startup time on deploy, you can trim the gems loaded at boot time (this doesn't mean you have to trim them from the app, just boot time).
gem_bench evaluates which gems are likely to not be needed at boot time.
I have an app with about 250 gems and was able to add :require => false to about 60 of them, with dramatic effects.
https://github.com/acquaintable/gem_bench
Disclaimer: I am the author of this open source ruby gem. I wrote the gem to aid myself in solving this exact problem: the 60 second timeout on Heroku.
The heroku-forward gem will help you beat the 60s Heroku timeout.

How do I stop rails from regenerating routes on every request?

I am working on a pretty large rails project with a lot of routes. If rails is in development mode the app runs extremely slowly because it has to generate the routes repeatedly. I've tested this a couple of times by removing most of the routes and our app is nearly instant in bringing up our pages rather than the 10 or so seconds it usually takes. What I'm trying to find out is how I can stop rails from regenerating the routes on every request when in development mode. Is there a way to cache it or just stop it from regenerating?
I wouldn't advise it, but set cache_classes to true in your config. You'll have to restart the server every time you want to test a code change though.
Did you get anywhere with this?
I'm a little late to the party, and I don't have a direct answer for stopping the regeneration of routes, but would you accept speeding up other parts of the development environment as a compromise? If so, it's worth checking out the Rails Development Boost gem. I've had some great speed increases from there.

Jruby rspec to be run parallely

Is there something like Spork for Jruby too? We want to parallelize our specs to run faster and pre-load the classes while running the rake task; however we have not been able to do so.
Since our project is considerable in size, specs take about 15 minutes to complete and this poses a serious challenge to quick turnaround.
Any ideas are more than welcome.
Cheers
Maybe you can try specjour, a system to distribute your test on several server.
http://github.com/sandro/specjour

Resources