Project Management and Scrum Software Alexander Dymo RailsConf 2009 Advanced Performance Optimization of Rails Applications http://en.oreilly.com/rails2009/public/schedule/detail/8615 www.acunote.com
What Am I Optimizing? Project Management and Scrum Software http://en.oreilly.com/rails2009/public/schedule/detail/8615 Acunote www.acunote.com Online project management and Scrum software Ruby on Rails application since inception in 2006 ● ~3700 customers ● Hosted on Engine Yard ● Hosted on Customers' Servers ● nginx + mongrel ● PostgreSQL Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 2 / 84
Performance Degradation Over Time Project Management and Scrum Software 300 Request Time (on development box), % Actually Happens: O(n c ) 250 Best Case: O(log n) 200 150 100 April 2008 May 2008 June 2008 July 2008 Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 3 / 84
Solutions? Project Management and Scrum Software Throw Some Hardware at it! Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 4 / 84
Solutions? Project Management and Scrum Software Performance Optimization! Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 5 / 84
Project Management and Scrum Software What to optimize? Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 6 / 84
What To Optimize? Project Management and Scrum Software Development? Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 7 / 84
What To Optimize? Project Management and Scrum Software Development AND Production Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 8 / 84
Project Management and Scrum Software How to optimize? Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 9 / 84
How To Optimize? Project Management and Scrum Software Three rules of performance optimization Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 10 / 84
Three Rules Of Performance Optimization Project Management and Scrum Software 1. Measure! ...the universal experience of programmers who have been using measurement tools has been that their intuitive guesses fail... Knuth Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 11 / 84
Three Rules Of Performance Optimization Project Management and Scrum Software 2. Optimize only what's slow! Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 12 / 84
Three Rules Of Performance Optimization Project Management and Scrum Software 3. Optimize for the user! Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 13 / 84
Things To Optimize Project Management and Scrum Software ● Development – Ruby code – Rails code – Database queries – Alternative Ruby ● Production – Shared filesystems and databases – Live debugging – Load balancing ● Frontend – HTTP – Javascript – Internet Explorer Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 14 / 84
Optimizing Ruby: Date Class Project Management and Scrum Software What's wrong with Date? > puts Benchmark.realtime { 1000.times { Time.mktime(2009, 5, 6, 0, 0, 0) } } 0.005 > puts Benchmark.realtime { 1000.times { Date.civil(2009, 5, 6) } } 0.080 16x slower than Time! Why? %self total self wait child calls name 7.23 0.66 0.18 0.00 0.48 18601 <Class::Rational>#reduce 6.83 0.27 0.17 0.00 0.10 5782 <Class::Date>#jd_to_civil 6.43 0.21 0.16 0.00 0.05 31528 Rational#initialize 5.62 0.23 0.14 0.00 0.09 18601 Integer#gcd Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 15 / 84
Optimizing Ruby: Date Class Project Management and Scrum Software Fixing Date: Use C, Luke! Date::Performance gem with Date partially rewritten in C by Ryan Tomayko (with my patches in 0.4.7) > puts Benchmark.realtime { 1000.times { Time.mktime(2009, 5, 6, 0, 0, 0) } } 0.005 > puts Benchmark.realtime { 1000.times { Date.civil(2009, 5, 6) } } 0.080 > require 'date/performance' puts Benchmark.realtime { 1000.times { Date.civil(2009, 5, 6) } } 0.006 git clone git://github.com/rtomayko/date-performance.git rake package:build cd dist && gem install date-performance-0.4.7.gem Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 16 / 84
Optimizing Ruby: Date Class Project Management and Scrum Software Real-world impact of Date::Performance: Before: 0.95 sec After: 0.65 sec 1.5x! Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 17 / 84
Optimizing Ruby: Misc Project Management and Scrum Software Use String::<< instead of String::+= > long_string = "foo" * 100000 > Benchmark.realtime { long_string += "foo" } in theory: 75x 0.0003 in practice: up to 70x > Benchmark.realtime { long_string << "foo" } 0.000004 Avoid BigDecimal comparisons with strings and integers > n = BigDecimal("4.5") in theory: 4.5x > Benchmark.realtime { 10000.times { n <=> 4.5 } } in practice: 1.15x 0.063 > Benchmark.realtime { 10000.times { n <=> BigDecimal("4.5") } } 0.014 Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 18 / 84
Things To Optimize Project Management and Scrum Software ● Development – Ruby code – Rails code – Database queries – Alternative Ruby ● Production – Shared filesystems and databases – Live debugging – Load balancing ● Frontend – HTTP – Javascript – Internet Explorer Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 19 / 84
Optimizing Rails: Preloading Associations Project Management and Scrum Software Preloading associations is always a good idea... except when Rails can't do the job: class Foo belongs_to :bar end foos = Foo.find_by_sql('select * from foos inner join bar') foos.first.bar #extra SQL query! Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 20 / 84
Optimizing Rails: Preloading Associations Project Management and Scrum Software Virtual Attributes plugin: http://github.com/acunote/virtual_attributes/ class Bar end class Foo belongs_to :bar preloadable_association :bar end foos = Foo.find_by_sql(' select * from foos left outer join (select id as preloaded_bar_id, name as preloaded_bar_name from bars) as bars on foos.bar_id = bars.preloaded_bar_id') foos.first.bar #no extra SQL query! Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 21 / 84
Optimizing Rails: String Callbacks Project Management and Scrum Software What can be wrong with this code? class Task < ActiveRecord::Base before_save "some_check()" end ... 100.times { Task.create attributes } Kernel#binding is called to eval() the string callback That will duplicate your execution context in memory! More memory taken => More time for GC Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 22 / 84
Optimizing Rails: Partial Rendering Project Management and Scrum Software Not too uncommon, right? <% for object in objects %> #1000 times <%= render :partial => 'object', :locals => { :object => object } %> <% end %> We create 1000 View instances for each object here! Why? Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 23 / 84
Optimizing Rails: Partial Rendering Project Management and Scrum Software Template inlining for the resque: <% for object in objects %> #1000 times <%= render :partial => 'object', :locals => { :object => object }, :inline => true %> <% end %> list.rhtml _object.rhtml _object.rhtml _object.rhtml _object.rhtml list.rhtml _object.rhtml _object.rhtml _object.rhtml _object.rhtml Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 24 / 84
Optimizing Rails: Partial Rendering Project Management and Scrum Software Template Inliner plugin: http://github.com/acunote/template_inliner/ Real world effect from template inlining: Rendering of 300 objects, 5 partials for each object without inlining: 0.89 sec with inlining: 0.75 sec 1.2x Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 25 / 84
Things To Optimize Project Management and Scrum Software ● Development – Ruby code – Rails code – Database queries – Alternative Ruby ● Production – Shared filesystems and databases – Live debugging – Load balancing ● Frontend – HTTP – Javascript – Internet Explorer Alexander Dymo • Advanced Performance Optimization of Rails Applications • RailsConf 2009 26 / 84
Recommend
More recommend