1 / 39

Use C to Tune Your Rails Application

Use C to Tune Your Rails Application. by Jared Richardson Pragmatic author, process consultant, rails developer, and speaker. Why Bother?. Existing Libraries Legacy Hardware Libraries Re-write Hot Spots. Three Parts. Ruby C Extensions InlineRuby Rails and C. Tools We’ll Use. ruby

orien
Download Presentation

Use C to Tune Your Rails Application

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Use C to Tune Your Rails Application by Jared Richardson Pragmatic author, process consultant, rails developer, and speaker

  2. Why Bother? • Existing Libraries • Legacy Hardware Libraries • Re-write Hot Spots

  3. Three Parts • Ruby C Extensions • InlineRuby • Rails and C

  4. Tools We’ll Use • ruby • rails • gcc • mkmf • Ruby Inline

  5. Ruby C Extension • Fairly easy • Use a few conventions • Can even share variables

  6. What We Need • C code • Make file • Ruby code

  7. C Code #include "ruby.h" static VALUE cSampleC; static VALUE exec_me(VALUE self) { printf("\n\n exec_me, written in C, run from Ruby! \n\n"); return Qnil; } void Init_SampleC() { cSampleC = rb_define_class("SampleC", rb_cObject); rb_define_method(cSampleC, "exec", exec, 0); }

  8. C Code #include "ruby.h" static VALUE cSampleC; static VALUE exec_me(VALUE self) { printf("\n\n exec_me, written in C, run from Ruby! \n\n"); return Qnil; } void Init_SampleC() { cSampleC = rb_define_class("SampleC", rb_cObject); rb_define_method(cSampleC, "exec", exec, 0); }

  9. C Code #include "ruby.h" static VALUE cSampleC; static VALUE exec_me(VALUE self) { printf("\n\n exec_me, written in C, run from Ruby! \n\n"); return Qnil; } void Init_SampleC() { cSampleC = rb_define_class("SampleC", rb_cObject); rb_define_method(cSampleC, "exec", exec, 0); }

  10. C Code #include "ruby.h" static VALUE cSampleC; static VALUE exec_me(VALUE self) { printf("\n\n exec_me, written in C, run from Ruby! \n\n"); return Qnil; } void Init_SampleC() { cSampleC = rb_define_class("SampleC", rb_cObject); rb_define_method(cSampleC, "exec", exec, 0); }

  11. C Code #include "ruby.h" static VALUE cSampleC; static VALUE exec_me(VALUE self) { printf("\n\n exec_me, written in C, run from Ruby! \n\n"); return Qnil; } void Init_SampleC() { cSampleC = rb_define_class("SampleC", rb_cObject); rb_define_method(cSampleC, "exec_me", exec_me, 0); }

  12. extconf.rb require 'mkmf'create_makefile("SampleC") To create your Makefile… ruby -r mkmf extconf.rb

  13. Practical Tip • If mkmf isn't installed, you'll see "ruby: no such file to load -- mkmf (LoadError)" • "sudo apt-get install ruby1.8-dev"

  14. Ruby Code require "SampleC“ handle = SampleC.new handle.exec_me

  15. Converting C to Ruby Objects • INT2NUM(int) => Fixnum • INT2NUM(long) => Fixnum • CHR2FIX(char) => Fixnum • rb_str_new2(char *) => String • rb_float_new(double) => Float

  16. Ruby Objects to C • int => NUM2INT(Numeric) • long => NUM2LONG(Numeric) • char * => STR2CSTR(String) • double => NUM2DBL(Numeric)

  17. Quick Demo

  18. Inline C • Ruby gem • gem install RubyInline

  19. Ruby Inline Code require "rubygems" require "inline" class RubyToC inline do |builder| builder.c %Q{ public void exec_me() { printf("Written in C, run from Ruby."); } } end end t = RubyToC.new() t.exec_me

  20. Ruby Inline Code require "rubygems" require "inline" class RubyToC inline do |builder| builder.c %Q{ public void exec_me() { printf("Written in C, run from Ruby."); } } end end t = RubyToC.new() t.exec_me

  21. Ruby Inline Code require "rubygems" require "inline" class RubyToC inline do |builder| builder.c %Q{ public void exec_me() { printf("Written in C, run from Ruby."); } } end end t = RubyToC.new() t.exec_me

  22. Ruby Inline Code require "rubygems" require "inline" class RubyToC inline do |builder| builder.c %Q{ public void exec_me() { printf("Written in C, run from Ruby."); } } end end t = RubyToC.new() t.exec_me

  23. Ruby Inline Code require "rubygems" require "inline" class RubyToC inline do |builder| builder.c %Q{ public void exec_me() { printf("Written in C, run from Ruby."); } } end end t = RubyToC.new() t.exec_me

  24. Ruby Inline Code require "rubygems" require "inline" class RubyToC inline do |builder| builder.c %Q{ public void exec_me() { printf("Written in C, run from Ruby."); } } end end t = RubyToC.new() t.exec_me

  25. Ruby Inline Code require "rubygems" require "inline" class RubyToC inline do |builder| builder.c %Q{ public void exec_me() { printf("Written in C, run from Ruby."); } } end end t = RubyToC.new() t.exec_me

  26. Ruby Inline Code require "rubygems" require "inline" class RubyToC inline do |builder| builder.c %Q{ public void exec_me() { printf("Written in C, run from Ruby."); } } end end handle = RubyToC.new() handle.exec_me

  27. That’s the Ruby • What about Rails? • Find the hot spots

  28. Rails Logging Processing MainController#search_students (for 127.0.0.1 at 2007-07-03 15:29:26) [GET] Session ID: b4c3826607bd5ff51f3fa34b45d96c76 Parameters: {"action"=>"search_students", "controller"=>"main"} Student Columns (0.001862) SHOW FIELDS FROM students Student Load (0.000149) SELECT * FROM students WHERE (students.`user_name` = 'jared') LIMIT 1 Student Load (0.000171) SELECT * FROM students WHERE (students.`city` = 'Gotham' AND students. Found 13 matches Rendering main/index Rendered main/_logo (0.00008) Rendered main/_tabs (0.00012) Rendered main/_top_of_page (0.00167) Rendered main/_search_students (0.00639) Rendered main/_nav_left_hand_side (0.00088) Rendered main/_footer (0.00010) Completed in 0.02753 (36 reqs/sec) | Rendering: 0.01113 (40%) | DB: 0.00298 (10%) | 200 OK [http://blah_mongrel/main/search_students]

  29. Rails Logging Processing MainController#search_students (for 127.0.0.1 at 2007-07-03 15:29:26) [GET] Session ID: b4c3826607bd5ff51f3fa34b45d96c76 Parameters: {"action"=>"search_students", "controller"=>"main"} Student Columns (0.001862) SHOW FIELDS FROM students Student Load (0.000149) SELECT * FROM students WHERE (students.`user_name` = 'jared') LIMIT 1 Student Load (0.000171) SELECT * FROM students WHERE (students.`city` = 'Gotham' AND students. Found 13 matches Rendering main/index Rendered main/_logo (0.00008) Rendered main/_tabs (0.00012) Rendered main/_top_of_page (0.00167) Rendered main/_search_students (0.00639) Rendered main/_nav_left_hand_side (0.00088) Rendered main/_footer (0.00010) Completed in 0.02753 (36 reqs/sec) | Rendering: 0.01113 (40%) | DB: 0.00298 (10%) | 200 OK [http://blah_mongrel/main/search_students]

  30. Rails Logging Completed in 0.02753 (36 reqs/sec) | Rendering: 0.01113 (40%) | DB: 0.00298 (10%) | 200 OK [http://blah_mongrel/main/search_students]

  31. Quick and Dirty start = Time.now # run code in here … done = Time.now elapsed_time = done - start logger.info("Spent #{elapsed_time} secconds ")

  32. Tuning Algorithm • Watch the log • Find slow controllers • Zero in with timing statements • Convert to C

  33. More on Tuning Rails http://www.rubyinside.com/how-to-profile-your-rails-application-and-make-rails-go-vroom-565.html

  34. Demo • Native Ruby on Rails • Rails with Inline C • Rails with Ruby C Extension

  35. Rails and Ruby Inline • Reloads break Inline • Put code in /lib • Or run in production mode

  36. Rails and C Extensions • Be sure to "make install" • Then require "Sample_C"

  37. Existing C Extensions • Rexml (ruby) vs. libxml (C) • 10x faster

  38. Web Resources • http://www.rubycentral.com/pickaxe/ext_ruby.html • http://www.zenspider.com/ZSS/Products/RubyInline/ • http://www.jaredrichardson.net/blog/2006/03/25/ • http://libxml.rubyforge.org/ • http://agileartisans.com/main/blog/41 • http://www.rubyinside.com/how-to-profile-your-rails-application-and-make-rails-go-vroom-565.html

More Related