4 ms·
From experience I have to agree with both parts of this - it can be very slow and it's generally not that easy to profile, e.g. the call graph tends to get very
by pcowans 15y ago
From experience I have to agree with both parts of this - it can be very slow and it's generally not that easy to profile, e.g. the call graph tends to get very complex and therefore difficult to interpret, and as you say, GC can be a big part of the problem which doesn't help.
One thing worth mentioning: anecdotally I've found that ActiveRecord can have an impact on performance far beyond the cost of the database queries, both by directly adding a reasonable amount of overhead and by instantiating a lot of objects internally which in turn triggers a lot of garbage collection. I wouldn't be surprised if that accounts for a fair chunk of what you're seeing.
- pcowans 15y agoI should also add that addressing performance issues with caching can seriously impact the maintainability of your application, particularly if you end up with complex cache expiry rules and/or systems to pre-populate cache entries. I'd definitely say that the priority should be to first simplify your app as much as possible, then optimise and only when that doesn't work to use caching.
- joevandyk 15y agoAgreed 100%. I've worked hard to remove all forms of caching from my sites. It simplifies things tremendously. I've found that database views and functions are one of the easiest ways to improve performance in Rails. FOR EXAMPLE To generate user's information shown above each comment for https://img.skitch.com/20120220-pununfygpsaw1cw5gmjin8e95i.png https://img.skitch.com/20120220-pununfygpsaw1cw5gmjin8e95i.p..., I have to get the user's username, the total amount of "points" the user has, the user's profile image, if the user is an admin (admins are formatted differently), etc. This information is stored across around 5 or 6 tables. Enter this view (which calls a few db functions): CREATE VIEW user_profile_info AS SELECT users.id AS user_id, users.slug AS user_slug, users.username, user_stats.total_points, user_profile_image(users.id) AS profile_image, is_user_admin(users.id) AS admin FROM (users JOIN user_stats ON (( user_stats.user_id = users.id ))); Now, I can have a simple UserProfileInfo ActiveRecord class that wraps this user_profile_info database view. Then I can do: @object.comments.includes(:user_profile_info) and, very efficiently, I get a list of comments and all the user's information. If I didn't use this approach, I would have to have a complex caching scheme to avoid the multiple sql queries. The goal is to minimize the amount of data that comes over the wire via sql queries (which also reduces the amount of work ActiveRecord has to do to construct these objects in memory). BTW, I'm starting to write a book about using postgresql effectively with web applications. I've found that there are tons of web developers (especially in Rails) that don't use the full-power of postgresql correctly which leads to slow and buggy code.
- ruckusing 15y agoI'd be very interested in purchasing this book. Please keep us updated when its available.