devroom.io/content/posts/2011-09-24-rspec-speed-up-by-tweaking-ruby-garbage-collection.md

60 lines
2.0 KiB
Markdown
Raw Normal View History

2017-03-20 15:35:19 +00:00
+++
date = "2011-09-24"
title = "RSpec speed-up (24.6%) by tweaking ruby garbage collection"
tags = ["Ruby", "Rails", "rspec", "speed", "garbage collection", "GC"]
slug = "rspec-speed-up-by-tweaking-ruby-garbage-collection"
+++
2015-03-26 11:28:08 +00:00
[Today I learned][1] that Ruby garbage collection can be of huge importance to performance. More precisely, if Ruby does a lot of garbage collection it may slow down your code. Running garbage collection only every 10 or 20 seconds when running specs may increase performance dramatically.
At this time specs for Ariejan.net take an average of 25.29s to run. This is not bad, but in my opinion faster specs are better. After tweaking ruby garbage collection I got my specs to run in 19.05s, a **24.6% speed increase**!
[1]: http://37signals.com/svn/posts/2742-the-road-to-faster-tests
~
So, how do _you_ speed up _your_ tests?
The key is that you don't want ruby to decide when to do garbage collection for you. Instead, we'll tell Ruby when to do this, and we'll let it do it every 15 seconds.
To set this up for RSpec create a file `spec/support/deferred_garbage_collection.rb`:
2017-03-20 15:35:19 +00:00
``` ruby
class DeferredGarbageCollection
2015-03-26 11:28:08 +00:00
2017-03-20 15:35:19 +00:00
DEFERRED_GC_THRESHOLD = (ENV['DEFER_GC'] || 15.0).to_f
2015-03-26 11:28:08 +00:00
2017-03-20 15:35:19 +00:00
@@last_gc_run = Time.now
def self.start
GC.disable if DEFERRED_GC_THRESHOLD > 0
end
2015-03-26 11:28:08 +00:00
2017-03-20 15:35:19 +00:00
def self.reconsider
if DEFERRED_GC_THRESHOLD > 0 && Time.now - @@last_gc_run >= DEFERRED_GC_THRESHOLD
GC.enable
GC.start
GC.disable
@@last_gc_run = Time.now
2015-03-26 11:28:08 +00:00
end
2017-03-20 15:35:19 +00:00
end
end
```
2015-03-26 11:28:08 +00:00
Next, add the following to your `spec/spec_helper.rb` so rspec will use our deferred garbage collection.
2017-03-20 15:35:19 +00:00
``` ruby
config.before(:all) do
DeferredGarbageCollection.start
end
2015-03-26 11:28:08 +00:00
2017-03-20 15:35:19 +00:00
config.after(:all) do
DeferredGarbageCollection.reconsider
end
```
2015-03-26 11:28:08 +00:00
Now, when you run `rake spec` you should see a nice speed increase. Try to alter the threshold value a bit to see what gives your best performance:
2017-03-20 15:35:19 +00:00
``` ruby
DEFER_GC=20 rake spec
```
Enjoy!
2015-03-26 11:28:08 +00:00