This February 6th we are launching a new workshop: Advanced Rails. The workshop draws content from the Scaling Rails and Rails Antipatterns workshops, replacing them and creating best-of-breed content that will take your skill to the next level in creating well-crafted Rails applications that scale.
One of the topics we touch on is profiling and benchmarking your app. There are a number of tools available to achieve this, one of which is baked into Rails itself. Although we do discuss all of the great ways you can perform caching in a Rails app, experience has shown us that caching should be your last resource in your scaling strategy. Remember the two hardest things in computer science: Cache invalidation, naming things and off-by-one errors.
On to benchmarking, say you have identified an expensive method in one of your
models that needs to be tuned. One easy and straight-forward way to measure your
refactored process is to use the built in benchmarker to run quick tests. To get
set up, you need to add the
gem to your Gemfile, and have a properly patched ruby interpreter. I’m using the
gcdata patch for MRI 1.9.2:
rvm install 1.9.2-p180 --patch gcdata --name gcdata
Now let’s assume the following expensive method in the Account class:
class Account def self.expensive_method sleep(1) end end
We can now run a quick benchmark on that method by running it 10 times and taking some benchmarking measurements:
bundle exec rails benchmarker --runs 10 'Account.expensive_method' Loaded suite script/rails Started BenchmarkerTest#test_10 (0 ms warmup) wall_time: 0 ms memory: 0 Bytes objects: 0 gc_runs: 0 gc_time: 0 ms BenchmarkerTest#test_user_expensive_method (1.10 sec warmup) wall_time: 1.00 sec memory: 0 Bytes objects: 0 gc_runs: 0 gc_time: 0 ms Finished in 24.933979 seconds.
You can even run a profiler with
rails profiler 'Account.expensive_method' 10
flat and get more information on what’s being called and which components in
your system are taking longer.
With this quick benchmark, you can now create a second, hopefully optimized,
Account.expensive_method_fast and run them side-by-side, allowing you to
quickly measure two implementations of the same behavior, and allowing you to
quickly iterate to find the best solution.
This is just the tip of the iceberg. If you have some Rails experience and want to take it to the next level to grow your app into a well-factored and scalable system, check out our new Advanced Rails workshop.