Ruby Concurrency & Threads

27
Ruby Concurrency & Threads Anup Nivargi

description

Talk about Ruby Concurrency in Ruby MRI and Rubinius. Difference in Threading implementation in MRI Ruby and Rubinius with benchmarking, Threads Performance for CPU intensive tasks & IO Intensive Tasks.

Transcript of Ruby Concurrency & Threads

Page 1: Ruby Concurrency & Threads

Ruby Concurrency & ThreadsAnup Nivargi

Page 2: Ruby Concurrency & Threads

I <3 Ruby!

Page 3: Ruby Concurrency & Threads

Concurrency V Parallelism

Page 4: Ruby Concurrency & Threads

Ruby ImplementationsMRI, JRuby, Rubinius etc..

Page 5: Ruby Concurrency & Threads

Threads In Ruby

Page 6: Ruby Concurrency & Threads

thread_example.rb

def thread1 100.times do |i| puts "In Thread 1" endend

def thread2 100.times do puts "In Thread 2" endend

t1 = Thread.new { thread1 }t2 = Thread.new { thread2 }

t1.joint2.join

Page 7: Ruby Concurrency & Threads

CPU Intensive Tasks

Page 8: Ruby Concurrency & Threads

factorial.rb

require 'benchmark'

def factorial_with_range(range) (1..range).to_a.each_slice(range/4).to_a.each do |elements| elements.each {|element| factorial(element) } endend

def factorial_with_range_threaded(range) threads = [] (1..range).to_a.each_slice(range/4).to_a.each do |elements| threads << Thread.new do elements.each{|element| factorial(element) } end end threads.each(&:join)end

Page 9: Ruby Concurrency & Threads
Page 10: Ruby Concurrency & Threads

factorial.rb (contd)

def factorial(n) (1..n).to_a.inject(:*)end

Benchmark.bm(30) do |bm| [4000, 5000].each do |num| bm.report("Single Threaded #{num}") do factorial_with_range(num) end

bm.report("Multi Threaded #{num}") do factorial_with_range_threaded(num) end endend

Page 11: Ruby Concurrency & Threads

Ruby MRI Benchmarks

user system total realSingle Threaded 4000 10.230000 0.100000 10.330000 ( 10.419738)Multi Threaded 4000 10.340000 0.330000 10.670000 ( 10.770526)Single Threaded 5000 18.960000 0.490000 19.450000 ( 19.601181)Multi Threaded 5000 19.120000 0.730000 19.850000 ( 20.012569)

Rubinius Benchmarks

user system total realSingle Threaded 4000 6.228000 0.139000 6.367000 ( 6.413544)Multi Threaded 4000 0.003000 0.000000 0.003000 ( 4.565215)

Single Threaded 5000 11.519000 0.306000 11.825000 ( 11.937241)Multi Threaded 5000 0.002000 0.000000 0.002000 ( 9.129658)

Page 12: Ruby Concurrency & Threads

Why?

Page 13: Ruby Concurrency & Threads

GIL or GVLin Ruby MRI

Page 14: Ruby Concurrency & Threads
Page 15: Ruby Concurrency & Threads

But, there is a catch!

Page 16: Ruby Concurrency & Threads

IO Intensive Task

Page 17: Ruby Concurrency & Threads

server.rb

require "webrick"

server = WEBrick::HTTPServer.new :Port => 8000

server.mount_proc "/" do |req, res| sleep 1 res.body = "Hello World"end

trap 'INT' do server.shutdown end

server.start

Page 18: Ruby Concurrency & Threads

service.rb

require "benchmark"require "net/http"

def fetch(count) uri = URI.parse("http://localhost:8000/") threads = [] count.times do threads << Thread.new do Net::HTTP.get_response(uri) end end threads.each(&:join)end

Benchmark.bm(30) do |bm| bm.report("IO Service"){ fetch(20) }end

Page 19: Ruby Concurrency & Threads
Page 20: Ruby Concurrency & Threads

Rubinius Benchmarks

user system total realIO Service 0.014000 0.002000 0.016000 ( 1.037461)

Ruby MRI Benchmarks

user system total realIO Service 0.050000 0.030000 0.080000 ( 1.070662)

Page 21: Ruby Concurrency & Threads

Ahhhh!

Page 22: Ruby Concurrency & Threads

Threading Caveats

Page 23: Ruby Concurrency & Threads

Conclusion

Page 24: Ruby Concurrency & Threads

Online References

Code : https://github.com/anupnivargi/experiments/tree/master/threads

https://blog.engineyard.com/2013/ruby-concurrency

http://speakmy.name/2013/04/02/concurrent-programming-and-threads-in-ruby-reading-list/

https://blog.engineyard.com/2011/ruby-concurrency-and-you

http://merbist.com/2011/02/22/concurrency-in-ruby-explained/

Page 25: Ruby Concurrency & Threads

Questions?Anup Nivargi

@[email protected]

Page 26: Ruby Concurrency & Threads

Thank You!

Page 27: Ruby Concurrency & Threads