The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Top 10 Ruby on Rails performance tips

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Antonio Cangiano

Posts: 333
Nickname: acangiano
Registered: Dec, 2005

Antonio Cangiano is a Ruby hacker
Top 10 Ruby on Rails performance tips Posted: Feb 10, 2007 5:49 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Antonio Cangiano.
Original Post: Top 10 Ruby on Rails performance tips
Feed Title: Zen and the Art of Ruby Programming
Feed URL: http://programmingzen.com/category/ruby/feed/
Feed Description: Antonio Cangiano's blog about Ruby development.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Antonio Cangiano
Latest Posts From Zen and the Art of Ruby Programming

Advertisement

The performance of Ruby on Rails is influenced by many factors, particularly the configuration of your deployment server(s). However the application code can make a big difference and determine whether your site is slow or highly responsive. This short article is about some of the tips and best coding practices to improve performances in Rails only, and won’t attempt to cover the server configuration improvements for the various deployments options.

  1. Optimize your Ruby code: this may seem obvious, but a Rails application is essentially ruby code that will have to be run. Make sure your code is efficient from a Ruby standpoint. Take a look at your code and ask yourself if some refactoring is in order, keeping in mind performance considerations and algorithmic efficiency. Profiling tools are, of course, very helpful in identifying slow code, but the following are some general considerations (some of them may appear admittedly obvious to you):
    • When available use the built-in classes and methods, rather than rolling your own;
    • Use Regular Expressions rather than costly loops, when you need to parse and process all but the smallest text;
    • Use Libxml rather than the slower REXML if you are processing XML documents;
    • Sometimes you may want to trade off just a bit of elegance and abstraction for speed (e.g. define_method and yield can be costly);
    • The best way to resolve slow loops, is to remove them if possible. Not always, but in a few cases you can avoid loops by restructuring your code;
    • Simplify and reduce nested if/unless as much as you can and remember that the operator ||= is your friend;
    • Hashes are expensive data structures. Consider storing the value for a given key in a local variable if you need to recall the value a few times. More in general, it’s a good idea to store in a variable (local, instance or class variable) any frequently accessed data structure.
  2. Caching is good: caching can significantly speed up your application. In particular:
  3. Use your database to the full extent of the law :): don’t be afraid of using the cool features provided by your database, even if they are not directly supported by Rails and doing so means bypassing ActiveRecord. For example define stored procedures and functions, knowing that you can use them by communicating directly with the database through driver calls, rather than ActiveRecord high level methods. This can hugely improve the performance of a data bound Rails application.
  4. Finders are great but be careful: finders are very pleasant to use, enable you to write readable code and they don’t require in-depth SQL knowledge. But the nice high level abstraction come with a computational cost. Follow these rules of thumb:
    • Retrieve only the information that you need. A lot of execution time can be wasted by running selects for data that is not really needed. When using the various finders make sure to provide the right options to select only the fields required (:select), and if you only need a numbered subset of records from the resultset, opportunely specify a limit (with the :limit and :offset options).
    • Don’t kill your database with too many queries, use eager loading of associations through the include option:
      # This will generates only one query,
      # rather than Post.count + 1 queries
      for post in Post.find(:all, 
        :include => [ :author, :comments ])
        # Do something with post
      end
    • Avoid dynamic finders like MyModel.find_by_*. While using something like User.find_by_username is very readable and easy, it also can cost you a lot. In fact, ActiveRecord dynamically generates these methods within method_missing and this can be quite slow. In fact, once the method is defined and invoked, the mapping with the model attribute (username in our example) is ultimately achieved through a select query which is built before being sent to the database. Using MyModel.find_by_sql directly, or even MyModel.find, is much more efficient;
    • Be sure to use MyModel.find_by_sql whenever you need to run an optimized SQL query. Needless to say, even if the final SQL statement ends up being the same, find_by_sql is more efficient than the equivalent find (no need to build the actual SQL string from the various option passed to the method). If you are building a plugin that needs to be cross-platform though, verify that the SQL queries will run on all Rails supported databases, or just use find instead.
  5. Group operations in a transaction: ActiveRecord wraps the creation or update of a record in a single transaction. Multiple inserts will then generate many transactions (one for each insert). Grouping multiple inserts in one single transaction will speed things up.

    Insead of:

     my_collection.each do |q|
       Quote.create({:phrase => q})
     end
    Use:
    Quote.transaction do
     my_collection.each do |q|
       Quote.create({:phrase => q})
     end
    end

    or for rolling back the whole transaction if any insert fails, use:

    Quote.transaction do
     my_collection.each do |q|
       quote = Quote.new({:phrase => q})
       quote.save!
     end
    end
  6. Control your controllers: filters are expensive, don’t abuse them. Also, don’t overuse too many instance variables that are not actually required by your views (they are not light).
  7. Use HTML for your views: in your view templates don’t overuse helpers. Every time you use form helpers you are introducing an extra step. Do you really need a helper to write the HTML for a link, a textbox or a form for you? (You may even make your designer, who doesn’t know Ruby, happy!)
  8. Logging: configure your applications so that they log only the information that is absolutely vital to you. Logging is an expensive operation and an inappropriate level (e.g. Logger::DEBUG) can cripple your production application.
  9. Patch the GC: OK, not really a coding issue, but patching Ruby’s Garbage Collection is strongly advised and will improve the speed of your Ruby and Rails applications significantly.
  10. A final note:I don’t advocate premature optimization, but if you can, work on your code with these principles in mind (but don’t overdo it either). Last minute changes and tweaks are possible but less desirable than a “performance aware” style of coding. Profile your applications, benchmark them and have fun experimenting.

Read: Top 10 Ruby on Rails performance tips

Topic: Ruby Syntax: begin + else Previous Topic   Next Topic Topic: Rails Google Maps Plugin

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use