Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Ruby Performance - The Last Mile - RubyConf India 2016

1,844 views

Published on

Talk on how JRuby is bringing performance and concurrency to Ruby, delivered at RubyConf India, March 20, 2016 in Kochi, Kerala, India.

Published in: Software

Ruby Performance - The Last Mile - RubyConf India 2016

  1. 1. Ruby Performance The Last Mile
  2. 2. Charles Oliver Nutter @headius
  3. 3. I've spent ten years building
  4. 4. I love Ruby
  5. 5. I want Ruby to succeed
  6. 6. I believe JRuby is the way
  7. 7. Do you want performance today?
  8. 8. Do you want concurrency today?
  9. 9. Do you know JRuby?
  10. 10. What you love from Ruby • Latest Ruby language features • Mostly-same Ruby standard library • Pure-Ruby gems work great • Native gems with JRuby support • It walks like Ruby, talks like Ruby • It is Ruby!
  11. 11. With the power of the JVM • Fast JIT to native code • Fully parallel threading • Leading-edge garbage collectors • Access to Java, Scala, Clojure, ... • But it's still Ruby!
  12. 12. Do you know Jay?
  13. 13. Matz's Keynote
  14. 14. Performance
  15. 15. Concurrency
  16. 16. By 2020
  17. 17. But what about today?
  18. 18. Performance
  19. 19. What do you optimize for? • Easy to develop with: short time until first deploy • Fast startup: good response cycle at command line • Straight-line performance, many operations per second • Parallelism: utilize many cores to get more done
  20. 20. State of the Art: Production-quality Rubies
  21. 21. Production Quality? • Support for 99%+ of Ruby language features • Important parts of standard library • Runs typical Ruby applications and libraries • Healthy extension ecosystem • CRuby, JRuby are the only real options right now
  22. 22. CRuby (MRI) • Up until 1.9, AST interpreter • YARV bytecode VM introduced for 1.9.0 • GC and performance improvements through 2.x series • Ruby 2.3 is latest, released in December • Future work on JIT, GC, happening now
  23. 23. JRuby • Many redesigns since creation in 2001 • AST interpreter until 2007 • Simple AST-to-bytecode JIT until JRuby 9000 • Optimizing compiler with JIT for 9k • JRuby 9.0.5 is current, 9.1 in a couple weeks • Next-gen Truffle runtime in the works
  24. 24. Lies, damn lies, and benchmarks
  25. 25. CRuby: red/black tree 0 2 4 6 8 1.8.7 1.9.3 2.0 2.1 2.2 2.3
  26. 26. CRuby: red/black tree 0 0.625 1.25 1.875 2.5 1.8.7 1.9.3 2.0 2.1 2.2 2.3
  27. 27. JRuby: red/black tree 0 1.25 2.5 3.75 5 JRuby 9.1 CRuby 2.3
  28. 28. JRuby: red/black tree 0 1.25 2.5 3.75 5 JRuby 9.1 CRuby 2.3
  29. 29. JRuby: red/black tree 0 0.6 1.2 1.8 2.4 JRuby 9.1 CRuby 2.3 4x FASTER
  30. 30. Ruby Code
  31. 31. Ruby Code Parser JRuby AST
  32. 32. r JRuby AST Compiler JRuby IR
  33. 33. er JRuby IR JIT JVM Bytecode
  34. 34. What can we do with this?
  35. 35. Block Pass-through def foo(&b)
 bar(&b)
 end
 
 def bar
 yield
 end
  36. 36. Block Pass-through loop {
 puts Benchmark.measure {
 i = 0
 while i < 1_000_000
 i+=1
 foo { }; foo { }; foo { }; foo { }; foo { }
 end
 }
 }
  37. 37. Block Passing 0 0.55 1.1 1.65 2.2 CRuby 2.3 JRuby 1.7.24 JRuby 9.1
  38. 38. define_method define_method :add do |a, b|
 a + b
 end
  39. 39. define_method 0 0.25 0.5 0.75 1 CRuby 2.3 JRuby 1.7.24 JRuby 9.1
  40. 40. Postfix rescue foo rescue nil
  41. 41. csv.rb Converters Converters = {
 integer: lambda { |f|
 Integer(f.encode(ConverterEncoding)) rescue f
 },
 float: lambda { |f|
 Float(f.encode(ConverterEncoding)) rescue f
 },
  42. 42. Postfix rescue 0 3.5 7 10.5 14 CRuby 2.3 JRuby 9.1
  43. 43. 0 3.5 7 10.5 14 CRuby 2.3 JRuby 9.1 Postfix rescue
  44. 44. CRuby starts up the fastest
  45. 45. JRuby runs the fastest
  46. 46. And we're getting faster
  47. 47. Concurrency
  48. 48. Parallelism
  49. 49. Concurrency? Parallelism? • Parallelism happens on the harder, e.g. multi-core • Concurrency happens in the software, e.g. Thread API • You can have concurrency without parallelism • You can have both with JRuby
  50. 50. Parallelism in Ruby • On CRuby, usually process-level • Ruby threads prevented from running in parallel • Extensions, IO can opt to release lock • On JRuby, usually thread-level • Ruby thread == JVM thread == OS thread • Single-process, shared memory
  51. 51. A Mailing Queue • A simple example of concurrency • For each job, construct an email to send • Some computation added to make processing heavier • "Ruby Concurrency and Parallelism: A Practical Tutorial"
 https://www.toptal.com/ruby/ruby-concurrency-and-parallelism-a- practical-primer
  52. 52. require "./lib/mailer"
 require "benchmark"
 
 puts Benchmark.measure{
 (ARGV[0] || 10_000).times do |i|
 Mailer.deliver do
 from "eki_#{i}@eqbalq.com"
 to "jill_#{i}@example.com"
 subject "Threading and Forking (#{i})"
 body "Some content"
 end
 end
 }
  53. 53. POOL_SIZE = (ARGV[0] || 10).to_i
 
 jobs = Queue.new
 
 (ARGV[1] || 10_000).to_i.times{|i| jobs.push i}
 
 workers = (POOL_SIZE).times.map do
 Thread.new do
 begin
 while x = jobs.pop(true)
 Mailer.deliver do
 ...
 end
 end
 rescue ThreadError
 end
 end
 end
 
 workers.map(&:join)
  54. 54. CRuby: mailer * 1000 TimeinSeconds 0 37.5 75 112.5 150 synchronous 4 threads 4 forks
  55. 55. JRuby: mailer * 1000 0 7 14 21 28 Synchronous 4 Threads
  56. 56. JRuby vs MRI Times Improvement 0 0.85 1.7 2.55 3.4 CRuby Forks JRuby Threads 3.37x 3.09x
  57. 57. But Threads are bad, right?
  58. 58. Most users will never Thread.new
  59. 59. You'll deploy one Rails server for your entire site
  60. 60. You'll cut your instances ten times
  61. 61. Or maybe 100 times
  62. 62. Libraries and frameworks will Thread.new for you
  63. 63. And on JRuby, you'll have more efficient apps
  64. 64. So we're done?
  65. 65. Move to JRuby
  66. 66. Now your app is fast!
  67. 67. Right?
  68. 68. It is possible to write efficient Ruby code
  69. 69. But it's very easy to write inefficient Ruby code
  70. 70. Great Features, Hidden Costs • Blocks are expensive to create, slower than method calls • case/when is an O(n) cascade of calls • Singleton classes/methods are costly and hurt method cache • Literal arrays, hashes, strings have to be constructed, GCed • Flow-control exceptions can be very expensive and hard to find
  71. 71. What happens if your code does not run fast enough?
  72. 72. You need to know your app
  73. 73. You need good tools
  74. 74. And the JVM has great tools
  75. 75. CRuby Tooling • Basic GC stats built in • Simple profilers in standard library • Some third-party tools • stackprof, ruby-prof, perftools.rb, ...
  76. 76. JVM tooling is JRuby tooling
  77. 77. JVM Tooling • Wide range of GCs: parallel, concurrent, realtime, pauseless • Built-in tools for analyzing GC, JIT, thread, IO, heap • Built-in remote monitoring via JMX • Dozens of tools out there for profiling, management, and more
  78. 78. VisualVM • Graphical console into your application • Monitor GC, threads, CPU usage • Sampled or full profiling with GUI browser • Live memory dumping, heap inspection • Ships with every OpenJDK install
  79. 79. Java Mission Control • Extremely low-overhead application recording • Analyze results offline in JMC • GC, CPU, heap events, IO operation all browsable • Commercial feature, free for development use
  80. 80. More on GC • JVM GCs are incredibly tunable with sensible defaults • Tools like http://gceasy.io and JClarity give you a deeper view • These are the best GCs and the best tools in the world
  81. 81. Finding Bottlenecks
  82. 82. Profiling
  83. 83. Profiling Tools • Command line options: --profile, --sample • JVM command-line profilers like prof • Many graphical sampling/complete profiling options • Flame graphs, stack profilers, you name it!
  84. 84. ...and this is just the beginning
  85. 85. Wrapping Up
  86. 86. Ruby is alive and well
  87. 87. CRuby continues to improve
  88. 88. Ruby 3 is very exciting
  89. 89. JRuby is performance today
  90. 90. JRuby is concurrency today
  91. 91. JRuby has tools today
  92. 92. JRuby makes you happier!
  93. 93. Thank You! Charles Oliver Nutter headius@headius.com @headius http://jruby.org https://github.com/jruby/jruby

×