Upgrade from Ruby 1.9.3 to Ruby 2.0.0 now!

TL;DR: Upgrade to Ruby 2.0.0 now!


This article is not a guide on upgrading. Plenty of tools make this easy (like RVM) and plenty of articles on the web that describe the process. This article looks at some nice speed boosts you’ll gain by upgrading. Ruby 2.0.0 is nearly a piece of cake to upgrade. On a fairly large application, not one of my tests failed when I switched from 1.9.3 to 2.0.

After upgrading, you’ll notice some speed boosts. Here are some I measured. These continue of from the last set of benchmarks I did last year (“Dramatically speeding up Ruby 1.9.3”) and using the same computer and compile flags as I used in that article.

% time ruby -e "count = 0; while(count < 100000000); count = count + 1; end; puts count"
Before: 3.2s
After: 2.0s

% time bundle exec rails runner 'true'
Before: 6.6s
After: 4.9s

% time bundle exec rake routes
Before: 6.8s
After: 4.9s

% time bundle exec rspec spec
Before: 3m 17s
After: 2m 53s

Conclusion:

The speed boosts are good, and as the ruby GC (among other things) gets better, these will improve even more. The upgrade is simple, and issue free. You’re doing yourself and those that work with you a dis-service if you don’t plan to upgrade to Ruby 2.0.0 soon.

Dramatically Speeding Up Ruby 1.9.3

After reinstalling Ruby 1.9.3 recently, it felt a lot slower than it was previously. Thankfully, I stumbled upon some blog posts that deal with this issue. Check these out:

http://spin.atomicobject.com/2012/11/06/is-your-application-running-with-ruby-slow/
http://alisnic.net/blog/making-your-ruby-fly/

I decided to give it a go. I didn’t compile ruby with the falcon patch, just stock ruby 1.9.3 with the CFLAGS set. I put the following into my ~/.rvmrc file:

rvm_configure_env=(CFLAGS="-march=nocona -O3 -fomit-frame-pointer -pipe")

(the march of nocona is for my computers CPU. You will need to find the correct one for your CPU or compiling will fail)

Then I ran ‘rvm reinstall 1.9.3’. Here are the results (the times are the lowest out of three runs of each command):

% time ruby -e "count = 0; while(count < 100000000); count = count + 1; end; puts count"
Before: 7.5s
After: 3.2s

% time bundle exec rails runner 'true'
Before: 12.4s
After: 6.6s

% time bundle exec rake routes
Before: 12.5s
After: 6.8s

% time bundle exec rspec spec
Before: 5m 53s
After: 3m 17s

Conclusion

If you haven’t compiled Ruby with optimizations, you’re unnecessarily slowing your application.

Updated 26th Nov 2012

I followed the additional advice in the references above and tried the falcon patch. The results are impressive. Check out these comparisons between just CFLAGS and CFLAGS+falcon patch.

% time ruby -e "count = 0; while(count < 100000000); count = count + 1; end; puts count"
Before: 3.2s
After: 3.2s

% time bundle exec rails runner 'true'
Before: 6.6s
After: 4.9s

% time bundle exec rake routes
Before: 6.8s
After: 5.0s

% time bundle exec rspec spec
Before: 3m 17s
After: 2m 57s

Conclusion

Set the CFLAGS for your system and compile ruby 1.9.3 with the falcon patch. You’ll save yourself a heaps of time :-)

Wrong way, Right way - Part 3 - Avoid unnecessary load in conditionals

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.

Wrong way, Right way - Part 2 - Work with eager loading, not against it

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.

Wrong way, Right way - Part 1 - Optimized conditional data sections

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.

Review: Gran Turismo 5

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.

Read More

How fast can your browser run? - Take 2

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.

Read More

How fast can your browser run?

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.

Read More

Migrating from Github to Gemcutter

( 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….

Read More

My Tools of the Trade

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.

Read More