Wednesday, August 7, 2013

131% faster Ruby tests, no new code needed

Some speed improvements on a Rails app test suite, about 100 assertions.

Initial state – Ruby 1.9.3-p448:

Total run time: 37s


First improvement – Ruby 1.9.3-p448 with Railsexpress patches:

Total run time: 31s
Improvement from initial state: +20%


Second improvement – Ruby 2.0.0-p247:

Total run time: 24s
Improvement from initial state: +54%


Last improvement – Ruby 2.0.0-p247 with GC tuning:
Total run time: 21s
Improvement from initial state: +75% !

Now I need to further tune the GC, I think I can double the original speed :)

Update:
I just installed ruby-2.0.0-head (right now, p290), and got even better results!

Total run time: 16s
Improvement from initial state: +131% !!!

And I still have to tune the GC...

Does anybody know what has changed between 2.0.0-p247 and 2.0.0-p290 to warrant the speed improvement?


Bonus! (this one touches code though) – feat. Stefan Kaes

The following code makes it so that the Rails env is initialized once for all the test suites, instead of three times (one per suite):

44
 
55
 require File.expand_path('../config/application', __FILE__)
66
 
7 
-XXX::Application.load_tasks
  
\ No newline at end of file
 7
+XXX::Application.load_tasks
 8
+
 9
+namespace :test do
 10
+  Rake::TestTask.new(:all) do |t|
 11
+    t.libs << "test"
 12
+    t.pattern = 'test/{lib,scripts,unit,functional,integration}/**/*_test.rb'
 13
+    t.verbose = true
 14
+  end
 15
+  tsk = Rake::Task['test:all']
 16
+  tsk.enhance(['test:prepare'])
 17
+  tsk.comment = "Run all tests in one go"
 18
+end
 19
+
 20
+Rake::Task['default'].clear_prerequisites
 21
+Rake::Task['default'].enhance ["test:all"]

5 comments:

  1. Nice, but can you give some more deatail about how are you running the GC?

    ReplyDelete
    Replies
    1. You can find all the info here:
      http://developingandstuff.blogspot.fr/2013/08/tuning-your-ruby-gc-for-fun-and-profit.html
      Hope that helps. If not, just ask me! :)

      Delete
  2. You do not need add new rake task for Rails 4, there is: `rake test:all` do this from box.

    ReplyDelete
    Replies
    1. Nice, thanks! We are not running Rails 4 yet here though :(

      Delete
  3. I should say that I like relying on Cobertura to validate my unit test pertinence. Something missing with Python...
    Application Testing

    ReplyDelete