Ruby-on-rails 4 slow performance

2019-07-20 14:37发布

问题:

I've seen significant performance problems after upgrading to Rails.

I've recently upgraded my project from Rails 2 and Ruby 1.8 to Rails 4 and Ruby 2.0. Reading around on the internet, I understand that upgrading should provide excellent performance improvement (up to 30%) out of the box. Unfortunately, I've found that the performance is a lot worse in some cases e.g. some reports that were previously taking around 20 seconds, now take 40 seconds.

I've seen some posts that suggest Garbage Collection may be the issue. After using some recommended settings, I've found that some of the longer reports are actually shorter, but the short reports are still much worse.

As part of the upgrade, I've moved over to unobtrusive javascript for the view rendering, but this doesn't seem to contribute to performance issues - most of the time is being spent in the model.

Does anybody know if I'm missing some configuration 'gotchas'? Did anybody else have performance problems as a result of the upgrade?

Thanks in advance.

回答1:

There are probably always going to be edge cases in upgrades, where certain types of operation run slower and other faster. It would probably be best to just follow regular performance tuning techniques and use tools such as the Oink gem and NewRelic to look analyse the slowest issues.

To be rigorous it's usually best to gather as much performance profiling data prior to the upgrade as possible so you can then tell whether a particular operation is suffering from higher memory consumption, more/slower garbage collection, different generated SQL (from an activerecord upgrade), more objects being created. With post-upgrade profiling it can be difficult to put the data in context so you can tell if the creation of 30 Post objects is normal for a given action, for example.

With respect to eager loading, we found bullet to be a very useful gem for getting the right level. You're right that it's not necessarily a Rails 3/4 issue, of course.

Another pain point for us has also been to not only reduce the number of queries but to be careful about whether we really need to create an object. You can sometimes get away with just retrieving the data for display without creating the object. Furthermore, we are now very careful about (for example) implicitly running:

select * from books where client_id = 1 order by name

... in order to create a dropdown of book names, when we could:

select id, name from books where client_id = 1 order by name

It is hugely more efficient on the Rails side, even if the difference in sometimes marginal on the database side (100ms vs 20ms on the database, but 2000ms vs 500ms on the Rails side).

Again, possibly not Rails 3/4 relevant unless there is a quirk in Rails 4 that makes it even less efficient, perhaps.