Note: I’ve been using this technique for a while that I’d forgotten I was doing it. Thumbs up to CollectiveIdea for their post which reminded me and inspired the following.
Part of a series about common Ruby mistakes that make things slower or are just plain wrong. Not the style of the code (indentation, methods names etc), but the actual code itself. All examples use Ruby 1.9.2 and Rails 3.0.x.
Part 3 - Avoid unnecessary load in conditionals
The Wrong Way
if post.comments.any? && post.author.present? && post.public?
puts post.comments.inspect
end
Whats wrong? The conditionals are executed in order. Suppose the post isn’t even public. Before we even get to that check at the end, we’ve hit the database twice; once to check for comments, and another to check for an author. 2 database queries that didn’t need to be run. This may not seem like much, but when you’ve got many of them in your app, you may be causing yourself unnecessary page load times.
The Right Way
if post.public? && post.author_id? && post.comments.any?
puts post.comments.inspect
end
Whats better? We check if the post is public right away. If it isn’t, we’ve saved ourselves unneeded queries. On top of that, since we don’t use the author inside the block, we don’t need to load them. All the check wanted to know is if they have an author id. Rails provides a nice boolean style method for every field on an ActiveRecord model. So lets use them, in that case, utilizing ‘author_id?’ to check for an author without any additional queries. Then, finally, the comments are loaded, only when the other two, less time consuming checks have passed.
Questions? Comments? Let me know what you thought.
Part of a series about common Ruby mistakes that make things slower or are just plain wrong. Not the style of the code (indentation, methods names etc), but the actual code itself. All examples use Ruby 1.9.2 and Rails 3.0.x.
Part 2 - Work with eager loading, not against it
The Wrong Way
class Post < ActiveRecord::Base
def last_comment
comments.order(:position).last
end
end
Post.includes(:comments).each do |post|
puts post.last_comment
end
Whats wrong? The last_positioned_comment instance method on Post is adding an order to comment query, which negates the includes(:comments) part of the Post select query. As a result, you’ll get one query for all posts, one query for all comments, and one query for each post to get the last comment. (pattern: 1P + 1C + 1*P)
The Right Way
class Post < ActiveRecord::Base
def last_comment
comments.sort_by(&:position).last
end
end
Post.includes(:comments).each do |post|
puts post.last_comment
end
Whats better? Because no extra sort is added to the comments, the ones that were preloaded still match. So you end up with only two queries, one for all posts, and one for all comments. (pattern: 1P + 1C). To end up getting the proper sorting, you simply use Ruby’s sort_by method along with symbol to proc syntax to create a nice clean implementation that works with eager loading.
Questions? Comments? Let me know what you thought.
Part of a series about common Ruby mistakes that make things slower or are just plain wrong. Not the style of the code (indentation, methods names etc), but the actual code itself. All examples use Ruby 1.9.2 and Rails 3.0.x.
Part 1 - Optimized conditional data sections
The Wrong Way
@comments = Comment.order(:position)
if @comments.count > 0
@comments.each do |comment|
…
end
end
Whats wrong? The conditional fires one query for count, and then the loop fires another one to get them again and instantiate them.
The Right Way
@comments = Comment.order(:position)
if @comments.to_a.any?
@comments.each do |comment|
…
end
end
Whats better? Only one query is made. The conditional loads the records, so if there are any to loop over, they are already loaded and ready to go without an extra query.
Questions? Comments? Let me know what you thought.
TL;DR: Scan the post for tips. They’re prefixed with ‘Tip:’, then read the Pros, Cons, Missing, and more Tips are the bottom.
So I bought Gran Turismo 5 (GT5) a week ago, and I’ve been playing it with every free minute I can get. I’ve been a fan of the GT series since I bought GT3 back in 2003. So I’ve been waiting for GT5 for a while now.
I bought the standard edition (‘cause lets face it, a book of pictures, a wallet, a key ring, and a model car aren’t worth the extra $250 the Collectors edition costs).
Here’s my experience so far and what I think of the game.
TL:DR: Google Chrome has pulled ahead of Webkit in terms of JS speed and feature completeness, however, it hasn’t utilized the graphics card well enough on the Mac.
It’s been nearly five months since I last did one of these. In that time, Chrome has gone from v6 to v8, Webkit has had close to 10,000 commits, and Minefield has gotten even closer to being released as Firefox 4.
So I thought it was about time that I tested the latest versions of them again. This time around, I added a few additional tests. HTML 5 is quite a hot topic right now, so is rendering on the graphics card. So I’ve added a few tests for that, to see how each is faring.
I wanted to see which browser has the latest and greatest in both rendering engine and javascript engine, so using three well known tests, I put the latest available browser versions for Mac to the test.
What was tested?
The following browsers were tested:
For those unaware, Chromium is the latest semi-stable version of Chrome, Minefield is Firefox’s latest, and Webkit is Safari’s latest. I couldn’t find a development build of Opera, so used the latest available.
For anyone impatient, I’ll come right out and say it: Webkit and Chromium are tied. Keep on reading to see how.
( cross-posted from http://blog.katipo.co.nz )
For those of you who follow this sort of thing, Github shut down their gem building. Thankfully, a newer and easier gem hoster, Gemcutter, appeared on the scene not long before that happened. The idea behind it, for those who haven’t heard of it, is that you manage your own gem building. Gemcutter doesn’t wait for your Gem spec to change before it makes a new gem. You simply build it locally, and push it to Gemcutter, using a handy gem they provide that extends Rubygems ‘gem’ console command.
But Github was building gems for some time, and due to it’s continuing popularity, many well known Ruby on Rails developers and companies switched permanently to Github for their gem building/hosting at the time, so it’s likely that quite a few gems you’ve got installed are from Github.
To help transition over from Github to Gemcutter, Maxim Chernyak wrote a great utility called off_github, which looks at your list of gems, and tells you which ones you’re installed from Github, and whether they can be reinstalled from Gemcutter. It saves a lot of time and effort than having to do it manually. So here’s how to get started….
A bunch of these posts going around. Thought I’d chime in and list what using day to day. I’ve swapped a lot of software recently with what I consider better software.
The application I work on (http://kete.net.nz) has an image sizes sysem setting that allows site administrators to changes the resized dimensions when someone uploads a photo. But we ran into case where someone drastically changes the dimensions after already adding several hundred photos. Can’t upload them all again!
While developing Kete, maintaining cross browser compatibility is a concern for us. We need to make sure that the site runs the same on Internet Explorer 6, Internet Explorer 7, Firefox 3, and Safari 4. As anyone who has tried can tell you, testing with Internet Explorer on a non Windows machine is not easy, but there is a way!