ruby concurrency & threads

Post on 12-May-2015

986 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

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

Ruby Concurrency & ThreadsAnup Nivargi

I <3 Ruby!

Concurrency V Parallelism

Ruby ImplementationsMRI, JRuby, Rubinius etc..

Threads In Ruby

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

CPU Intensive Tasks

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

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

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)

Why?

GIL or GVLin Ruby MRI

But, there is a catch!

IO Intensive Task

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

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

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)

Ahhhh!

Threading Caveats

Conclusion

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/

Questions?Anup Nivargi

@therealnoopanupnivargi@gmail.com

Thank You!

top related