際際滷

際際滷Share a Scribd company logo
Code OptimizationsRuby128 minutes
Huh? Whats that?2
Why would I want to do that?MoneyResourcesHardwarePeople (Developers)TimeSpeed of operationDeveloper takes to figure out whats going onKarmaNo one wants to write bad code!3
4Ruby
Interpolation over Concatenationputs "This string embeds #{a} and #{b} through interpolation"# => fasterputs "This string concatenates "<< a <<" and "<< b  # => slowerputs "This string concatenates + a +" and "+ b  # => slower5
Destructive Operations!hash = {}hash =hash.merge({1=>2}) # duplicates the original hashhash.merge!({1=>2}) # equivalent to previous line, and fasterstr="string to gsub"str=str.gsub(/to/, 'copy') # duplicate string and reassigns itstr.gsub!(/to/, 'copy') # same effect, but no object duplication6
Benchmark everythingrequire 'benchmark'n =100000Benchmark.bm do |x| x.report('copy') { n.timesdo ; h = {}; h =h.merge({1=>2}); end }   x.report('no copy') { n.timesdo ; h = {}; h.merge!({1=>2}); end }end#          user       system     total       real# copy    0.460000   0.180000   0.640000  (0.640692)# no copy 0.340000   0.120000   0.460000  (0.463339)7
Symbols whenever possible'foo'.object_id# => 23233310'foo'.object_id# => 23228920:foo.object_id# => 239298:foo.object_id# => 2392988
Array joins[1, 2, 3] * 3# => [1, 2, 3, 1, 2, 3, 1, 2, 3][1, 2, 3] * '3'# => "13233"%w{thisisatest} * ", "# => "this, is, a, test"h = { :name=>"Fred", :age=>77 }h.map { |i| i * "=" } * ""# => "age=77name=Fred"9
Everything is an object!defadd(adder, addee)  adder +addeeendadd(3,5) # => 8classFixnumdefadd(num)self+ numendend3.add(5)# => 810
Use ranges instead of complex comparisons for numbers# No more if x > 1000 && x < 2000 nonsense. Instead:year =1972puts  case yearwhen1970..1979:"Seventies"when1980..1989:"Eighties"when1990..1999:"Nineties"end11
Ruby logicdefis_odd(x)    if x % 2==0returnfalseelsereturntrueendenddefis_odd(x)  x % 2==0?false:trueenddefis_odd(x)  x % 2!=0end12classFixnumdef odd?self % 2!=0endend2.odd? # => false
Enumerate single object# [*items] converts a single object into an array. And if the object is an array, keeps it as it is.[*items].each do |item|# ...end13
14Rails
CachingPage CachingFragment CachingAction CachingCaching into Local / Instance Variable15# Makes a database query only if @current_user is nildefcurrent_user@current_user||=User.find(session[:user_id])end
Dont limit yourself to ActiveRecordUse performance boosting database features like: Stored proceduresFunctionsX-query16
Finders are great but be carefulRetrieve only the information that you need.Dont kill your database with too many queries. Use eager loading.Avoid dynamic finders like MyModel.find_by_*.Need an optimized query? Run MyModel.find_by_sql.17#This will generates only one query,# rather than Post.count + 1 queriesfor post inPost.find(:all, :include=> [ :author, :comments ])# Do something with postend
Control your controllersDont let them become the God classes.Lesser instance variables.Slimmer the better.Appropriate code in appropriate controller.18
19And of course!
20Obey design principles.Always code in context (Objects). It is the best way to model your solution.Avoid Quick and dirty.Understand that no good can ever come out of duplication. Be it code, design, data and most importantly effort.Simplicity is the key.Enjoy coding!
21際際滷sslideshare.net/ihower/rails-best-practicesslideshare.net/ihower/practical-rails2-350619slideshare.net/preston.lee/logical-programming-with-ruby-prologRuby BooksThe Ruby Wayby Hal Edwin Fulton, Guy HurstThe Rails Wayby Obie FernandezDesign Patterns in Rubyby Russ OlsenSoftware ConstructionCode Complete 2by Steve McConnellThe Pragmatic Programmer: From Journeyman to Masterby Andrew Hunt

More Related Content

Ruby Code Optimizations (for beginners)

  • 3. Why would I want to do that?MoneyResourcesHardwarePeople (Developers)TimeSpeed of operationDeveloper takes to figure out whats going onKarmaNo one wants to write bad code!3
  • 5. Interpolation over Concatenationputs "This string embeds #{a} and #{b} through interpolation"# => fasterputs "This string concatenates "<< a <<" and "<< b # => slowerputs "This string concatenates + a +" and "+ b # => slower5
  • 6. Destructive Operations!hash = {}hash =hash.merge({1=>2}) # duplicates the original hashhash.merge!({1=>2}) # equivalent to previous line, and fasterstr="string to gsub"str=str.gsub(/to/, 'copy') # duplicate string and reassigns itstr.gsub!(/to/, 'copy') # same effect, but no object duplication6
  • 7. Benchmark everythingrequire 'benchmark'n =100000Benchmark.bm do |x| x.report('copy') { n.timesdo ; h = {}; h =h.merge({1=>2}); end } x.report('no copy') { n.timesdo ; h = {}; h.merge!({1=>2}); end }end# user system total real# copy 0.460000 0.180000 0.640000 (0.640692)# no copy 0.340000 0.120000 0.460000 (0.463339)7
  • 8. Symbols whenever possible'foo'.object_id# => 23233310'foo'.object_id# => 23228920:foo.object_id# => 239298:foo.object_id# => 2392988
  • 9. Array joins[1, 2, 3] * 3# => [1, 2, 3, 1, 2, 3, 1, 2, 3][1, 2, 3] * '3'# => "13233"%w{thisisatest} * ", "# => "this, is, a, test"h = { :name=>"Fred", :age=>77 }h.map { |i| i * "=" } * ""# => "age=77name=Fred"9
  • 10. Everything is an object!defadd(adder, addee) adder +addeeendadd(3,5) # => 8classFixnumdefadd(num)self+ numendend3.add(5)# => 810
  • 11. Use ranges instead of complex comparisons for numbers# No more if x > 1000 && x < 2000 nonsense. Instead:year =1972puts case yearwhen1970..1979:"Seventies"when1980..1989:"Eighties"when1990..1999:"Nineties"end11
  • 12. Ruby logicdefis_odd(x) if x % 2==0returnfalseelsereturntrueendenddefis_odd(x) x % 2==0?false:trueenddefis_odd(x) x % 2!=0end12classFixnumdef odd?self % 2!=0endend2.odd? # => false
  • 13. Enumerate single object# [*items] converts a single object into an array. And if the object is an array, keeps it as it is.[*items].each do |item|# ...end13
  • 15. CachingPage CachingFragment CachingAction CachingCaching into Local / Instance Variable15# Makes a database query only if @current_user is nildefcurrent_user@current_user||=User.find(session[:user_id])end
  • 16. Dont limit yourself to ActiveRecordUse performance boosting database features like: Stored proceduresFunctionsX-query16
  • 17. Finders are great but be carefulRetrieve only the information that you need.Dont kill your database with too many queries. Use eager loading.Avoid dynamic finders like MyModel.find_by_*.Need an optimized query? Run MyModel.find_by_sql.17#This will generates only one query,# rather than Post.count + 1 queriesfor post inPost.find(:all, :include=> [ :author, :comments ])# Do something with postend
  • 18. Control your controllersDont let them become the God classes.Lesser instance variables.Slimmer the better.Appropriate code in appropriate controller.18
  • 20. 20Obey design principles.Always code in context (Objects). It is the best way to model your solution.Avoid Quick and dirty.Understand that no good can ever come out of duplication. Be it code, design, data and most importantly effort.Simplicity is the key.Enjoy coding!
  • 21. 21際際滷sslideshare.net/ihower/rails-best-practicesslideshare.net/ihower/practical-rails2-350619slideshare.net/preston.lee/logical-programming-with-ruby-prologRuby BooksThe Ruby Wayby Hal Edwin Fulton, Guy HurstThe Rails Wayby Obie FernandezDesign Patterns in Rubyby Russ OlsenSoftware ConstructionCode Complete 2by Steve McConnellThe Pragmatic Programmer: From Journeyman to Masterby Andrew Hunt