SlideShare una empresa de Scribd logo
1 de 82
Descargar para leer sin conexión
Bringing Concurrency
to Ruby
Charles Oliver Nutter	

@headius
Me, about 40 weeks of the year
Me, the other 12 weeks of the year
Concurrency
Parallelism?
Concurrency
• Two or more jobs	

• Making progress	

• Over a given time span
Parallelism
• Two or more computations	

• Executing at the same moment in time
Examples
• Thread APIs: concurrency	

• Actore APIs: concurrency	

• Native thread, process: parallelism	

• If the underlying system supports it	

• SIMD, GPU, vector operations: parallelism
You Need Both
• Work that can split into concurrent jobs	

• Platform that runs those jobs in parallel	

• In an ideal world, scales with job count	

• In our world, each job adds overhead
Process-level
Concurrency
• Separate processes running concurrently	

• As parallel as OS/CPU can make them	

• Low risk due to isolated memory space	

• High memory requirements	

• High communication overhead
Thread-level
Concurrency
• Threads in-process running concurrently	

• As parallel as OS/CPU can make them	

• Higher risk due to shared memory space	

• Lower memory requirements	

• Low communication overhead
Popular Platforms
Concurrency Parallelism GC Notes
MRI 1.8.7 ✔ ✘ Single thread, stop-
the-world
Large C core would
need much work
MRI 1.9+ ✔ ✘ Single thread, stop-
the-world
Few changes since
1.9.3
JRuby (JVM) ✔ ✔ Many concurrent
and parallel options
JVM is the “best”
platform for conc
Rubinius ✔ ✔
Single thread, stop-
the-world, partial
concurrent old gen
Promising, but a
long road ahead
Topaz ✘ ✘ Single thread, stop-
the-world
Incomplete impl
Node.js (V8) ✘ ✘ Single thread, stop-
the-world
No threads in JS
CPython ✔ ✘ Reference-counting
Reference counting
kills parallelism
Pypy ✔ ✘ Single thread, stop-
the-world
Exploring STM to
enable concurrency
Idle System
MRI 1.8.7, One Thread
MRI 1.8.7, Eight Threads
Timeslicing
Thread 1
Thread 2
Thread 3
Thread 4
Native thread
Native thread
Native thread
Native thread
“Green” or “virtual” or “userspace” threads share	

a single native thread.The CPU then schedules	

that thread on available CPUs.
Time’s up
Time’s up Time’s up
MRI 1.8.7, Eight Threads
MRI 1.9.3+, Eight Threads
GVL: GlobalVM Lock
Thread 1
Thread 2
Thread 3
Thread 4
CPU
CPU
CPU
CPU
In 1.9+, each thread gets its own native thread,	

but a global lock prevents concurrent execution.	

Time slices are finer grained and variable, but	

threads still can’t run in parallel.
Lock xfer
CPU
Lock xfer Lock xfer
GVL: GlobalVenue Lock
MRI 1.9.3+, Eight Threads
MRI 1.9.3+, Eight Threads
JRuby, One Thread
Why Do We See
Parallelism?
• Hotspot JVM has many background threads	

• GC with concurrent and parallel options	

• JIT threads	

• Signal handling	

• Monitoring and management
JRuby, One Thread
JRuby, Eight Threads
Time Matters Too
0
1.75
3.5
5.25
7
Time per iteration
MRI 1.8.7 MRI 1.9.3 JRuby
Nearly 10x	

faster than	

1.9.3
Rules of Concurrency
1. Don’t do it, if you don’t have to.	

2. If you must do it, don’t share data.	

3. If you must share data, make it immutable.	

4. If it must be mutable, coordinate all access.
#1: Don’t
• Many problems won’t benefit	

• Explicitly sequential things, e.g	

• Bad code can get worse	

• Multiply perf, GC, alloc overhead by N	

• Fixes may not be easy (esp. in Ruby)	

• The risks can get tricky to address
I’m Not Perfect
• Wrote a naive algorithm	

• Measured it taking N seconds	

• Wrote the concurrent version	

• Measured it taking roughly N seconds	

• Returned to original to optimize
Fix Single-thread First!Timeinseconds
0
5
10
15
20
big_list time
v1 v2 v3 v4
String slice instead of unpack/pack
Simpler loops
Stream from file
Timeinseconds
0
17.5
35
52.5
70
Processing 23M word file
Non-threaded Two threads Four threads
Before Conc Work
• Fix excessive allocation (and GC)	

• Fix algorithmic complexity	

• Test on the runtime you want to target	

• If serial perf is still poor after optimization,
the task, runtime, or system may not be
appropriate for a concurrent version.
Concurrency won’t help code
that’s using up all hardware
resources.
#2: Don’t Share Data
• Process-level concurrency	

• …have to sync up eventually, though	

• Threads with their own data objects	

• Rails request objects, e.g.	

• APIs with a “master” object, usually	

• Weakest form of concurrency
#3: Immutable Data
• In other words…	

• Data can be shared	

• Threads can pass it around safely	

• Cross-thread view of data can’t mutate	

• Threads can’t see concurrent mutations as
they happen, avoiding data races
Object#freeze
• Simplest mechanism for immutability	

• For read-only: make changes, freeze	

• Read-mostly: dup, change, freeze, replace	

• Write-mostly: same, but O(n) complexity
Immutable Data
Structure
• Designed to avoid visible mutation but still
have good performance characteristics	

• Copy-on-write is poor-man’s IDS	

• Better: persistent data structures like Ctrie
http://en.wikipedia.org/wiki/Ctrie
Persistent?
• Collection you have a reference to is
guaranteed never to change	

• Modifications return a new reference	

• …and only duplicate affected part of trie
Hamster
• Pure-Ruby persistent data structures	

• Set, List, Stack, Queue,Vector, Hash	

• Based on Clojure’s Ctrie collections	

• https://github.com/hamstergem/hamster
person = Hamster.hash(!
:name => “Simon",!
:gender => :male)!
# => {:name => "Simon", :gender => :male}!
 !
person[:name]!
# => "Simon"!
person.get(:gender)!
# => :male!
 !
friend = person.put(:name, "James")!
# => {:name => "James", :gender => :male}!
person!
# => {:name => "Simon", :gender => :male}!
friend[:name]!
# => "James"!
person[:name]!
# => "Simon"
Coming Soon
• Reimplementation by Smit Shah	

• Mostly “native” impl of Ctrie	

• Considerably better perf than Hamster	

• https://github.com/Who828/persistent_data_structures
Other Techniques
• Known-immutable data like Symbol, Fixnum	

• Mutate for a while, then freeze	

• Hand-off: if you pass mutable data, assume
you can’t mutate it anymore	

• Sometimes enforced by runtime, e.g.
“thread-owned objects”
#4: Synchronize Mutation
• Trickiest to get right; usually best perf	

• Fully-immutable generates lots of garbage	

• Locks, atomics, and specialized collections
Locks
• Avoid concurrent operations	

• Read + write, in general	

• Many varieties: reentrant, read/write	

• Many implementations
Mutex
• Simplest form of lock	

• Acquire, do work, release	

• Not reentrant
semaphore = Mutex.new!
...!
a = Thread.new {!
semaphore.synchronize {!
# access shared resource!
}!
}
ConditionVariable
• Release mutex temporarily	

• Signal others waiting on the mutex	

• …and be signaled	

• Similar to wait/notify/notifyAll in Java
resource = ConditionVariable.new!
 !
a = Thread.new {!
mutex.synchronize {!
# Thread 'a' now needs the resource!
resource.wait(mutex)!
# 'a' can now have the resource!
}!
}!
 !
b = Thread.new {!
mutex.synchronize {!
# Thread 'b' has finished using the resource!
resource.signal!
}!
}!
Monitor
• Reentrancy	

• “try” acquire	

• Mix-in for convenience	

• Java synchronization = CondVar + Monitor
Monitor
require 'monitor'!
 !
lock = Monitor.new!
lock.synchronize do!
# exclusive access!
end
Monitor
require 'monitor'!
 !
class SynchronizedArray < Array!
 !
include MonitorMixin!
 !
alias :old_shift :shift!
 !
def shift(n=1)!
self.synchronize do!
self.old_shift(n)!
end!
end!
...
Atomics
• Without locking…	

• …replace a value only if unchanged	

• …increment, decrement safely	

• Thread-safe code can use atomics instead
of locks, usually with better performance
atomic
• Atomic operations for Ruby	

• https://github.com/headius/ruby-atomic
require 'atomic'!
 !
my_atomic = Atomic.new(0)!
my_atomic.value!
# => 0!
my_atomic.value = 1!
my_atomic.swap(2)!
# => 1!
my_atomic.compare_and_swap(2, 3)!
# => true, updated to 3!
my_atomic.compare_and_swap(2, 3)!
# => false, current is not 2
Specialized Collections
• thread_safe gem	

• Fully-synchronized Array and Hash	

• Atomic-based hash impl (“Cache”)	

• java.util.concurrent	

• Numerous tools for concurrency
Queues
• Thread-safe Queue and SizedQueue	

• Pipeline data to/from threads	

• Standard in all Ruby impls
thread_count = (ARGV[2] || 1).to_i!
queue = SizedQueue.new(thread_count * 4)!
!
word_file.each_line.each_slice(50) do |words|!
queue << words!
end!
queue << nil # terminating condition
threads = thread_count.times.map do |i|!
Thread.new do!
while true!
words = queue.pop!
if words.nil? # terminating condition!
queue.shutdown!
break!
end!
words.each do |word|!
# analyze the word
Putting It All Together
• These are a lot of tools to sort out	

• Others have sorted them out for you
Celluloid
• Actor model implementation	

• OO/Ruby sensibilities	

• Normal classes, normal method calls	

• Async support	

• Growing ecosystem	

• Celluloid-IO and DCell (distributed actors)	

• https://github.com/celluloid/celluloid
class Sheen!
include Celluloid!
 !
def initialize(name)!
@name = name!
end!
 !
def set_status(status)!
@status = status!
end!
 !
def report!
"#{@name} is #{@status}"!
end!
end
>> charlie = Sheen.new "Charlie Sheen"!
=> #<Celluloid::Actor(Sheen:0x00000100a312d0) @name="Char
>> charlie.set_status "winning!"!
=> "winning!"!
>> charlie.report!
=> "Charlie Sheen is winning!"!
>> charlie.async.set_status "asynchronously winning!"!
=> nil!
>> charlie.report!
=> "Charlie Sheen is asynchronously winning!"
Sidekiq
• Simple, efficient background processing	

• Think Resque or DelayedJob but better	

• Normal-looking Ruby class is the job	

• Simple call to start it running in background	

• http://mperham.github.io/sidekiq/
class HardWorker!
include Sidekiq::Worker!
 !
def perform(name, count)!
puts 'Doing hard work'!
end!
end!
!
...later, in a controller...!
 !
HardWorker.perform_async('bob', 5)
Concurrent Ruby
• Grab bag of concurrency patterns	

• Actor,Agent, Channel, Future, Promise,
ScheduledTask,TimerTask, Supervisor	

• Thread pools, executors, timeouts,
conditions, latches, atomics	

• May grow into a central lib for conc stuff	

• https://github.com/jdantonio/concurrent-ruby
…all the examples I’ve shown you and more
Recap
• The future of Ruby is concurrent	

• The tools are there to help you	

• Let’s all help move Ruby forward
Thank you!
• Charles Oliver Nutter	

• headius@headius.com	

• @headius

Más contenido relacionado

La actualidad más candente

Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017Codemotion
 
JRuby with Java Code in Data Processing World
JRuby with Java Code in Data Processing WorldJRuby with Java Code in Data Processing World
JRuby with Java Code in Data Processing WorldSATOSHI TAGOMORI
 
Getting Started with Go
Getting Started with GoGetting Started with Go
Getting Started with GoSteven Francia
 
Building Awesome CLI apps in Go
Building Awesome CLI apps in GoBuilding Awesome CLI apps in Go
Building Awesome CLI apps in GoSteven Francia
 
How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?Hiroshi SHIBATA
 
HTTP::Parser::XS - writing a fast & secure XS module
HTTP::Parser::XS - writing a fast & secure XS moduleHTTP::Parser::XS - writing a fast & secure XS module
HTTP::Parser::XS - writing a fast & secure XS moduleKazuho Oku
 
Ruby is dying. What languages are cool now?
Ruby is dying. What languages are cool now?Ruby is dying. What languages are cool now?
Ruby is dying. What languages are cool now?Michał Konarski
 
Rust Programming Language
Rust Programming LanguageRust Programming Language
Rust Programming LanguageJaeju Kim
 
Kotlin - A very quick introduction
Kotlin - A very quick introductionKotlin - A very quick introduction
Kotlin - A very quick introductionMike Harris
 
Concurrency & Parallel Programming
Concurrency & Parallel ProgrammingConcurrency & Parallel Programming
Concurrency & Parallel ProgrammingRamazan AYYILDIZ
 
Mongo db - How we use Go and MongoDB by Sam Helman
Mongo db - How we use Go and MongoDB by Sam HelmanMongo db - How we use Go and MongoDB by Sam Helman
Mongo db - How we use Go and MongoDB by Sam HelmanHakka Labs
 
Fluentd at HKOScon
Fluentd at HKOSconFluentd at HKOScon
Fluentd at HKOSconN Masahiro
 
Implementing a JavaScript Engine
Implementing a JavaScript EngineImplementing a JavaScript Engine
Implementing a JavaScript EngineKris Mok
 
Briefly Rust - Daniele Esposti - Codemotion Rome 2017
Briefly Rust - Daniele Esposti - Codemotion Rome 2017Briefly Rust - Daniele Esposti - Codemotion Rome 2017
Briefly Rust - Daniele Esposti - Codemotion Rome 2017Codemotion
 
T4T Training day - NodeJS
T4T Training day - NodeJST4T Training day - NodeJS
T4T Training day - NodeJSTim Sommer
 
tDiary annual report 2009 - Sapporo Ruby Kaigi02
tDiary annual report 2009 - Sapporo Ruby Kaigi02tDiary annual report 2009 - Sapporo Ruby Kaigi02
tDiary annual report 2009 - Sapporo Ruby Kaigi02Hiroshi SHIBATA
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mrubyHiroshi SHIBATA
 

La actualidad más candente (20)

Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
 
JRuby with Java Code in Data Processing World
JRuby with Java Code in Data Processing WorldJRuby with Java Code in Data Processing World
JRuby with Java Code in Data Processing World
 
Getting Started with Go
Getting Started with GoGetting Started with Go
Getting Started with Go
 
IDLs
IDLsIDLs
IDLs
 
Building Awesome CLI apps in Go
Building Awesome CLI apps in GoBuilding Awesome CLI apps in Go
Building Awesome CLI apps in Go
 
How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?
 
HTTP::Parser::XS - writing a fast & secure XS module
HTTP::Parser::XS - writing a fast & secure XS moduleHTTP::Parser::XS - writing a fast & secure XS module
HTTP::Parser::XS - writing a fast & secure XS module
 
Ruby is dying. What languages are cool now?
Ruby is dying. What languages are cool now?Ruby is dying. What languages are cool now?
Ruby is dying. What languages are cool now?
 
Rust Programming Language
Rust Programming LanguageRust Programming Language
Rust Programming Language
 
Kotlin - A very quick introduction
Kotlin - A very quick introductionKotlin - A very quick introduction
Kotlin - A very quick introduction
 
Concurrency & Parallel Programming
Concurrency & Parallel ProgrammingConcurrency & Parallel Programming
Concurrency & Parallel Programming
 
Mongo db - How we use Go and MongoDB by Sam Helman
Mongo db - How we use Go and MongoDB by Sam HelmanMongo db - How we use Go and MongoDB by Sam Helman
Mongo db - How we use Go and MongoDB by Sam Helman
 
Rust 101 (2017 edition)
Rust 101 (2017 edition)Rust 101 (2017 edition)
Rust 101 (2017 edition)
 
Fluentd at HKOScon
Fluentd at HKOSconFluentd at HKOScon
Fluentd at HKOScon
 
Implementing a JavaScript Engine
Implementing a JavaScript EngineImplementing a JavaScript Engine
Implementing a JavaScript Engine
 
Briefly Rust - Daniele Esposti - Codemotion Rome 2017
Briefly Rust - Daniele Esposti - Codemotion Rome 2017Briefly Rust - Daniele Esposti - Codemotion Rome 2017
Briefly Rust - Daniele Esposti - Codemotion Rome 2017
 
T4T Training day - NodeJS
T4T Training day - NodeJST4T Training day - NodeJS
T4T Training day - NodeJS
 
JRuby: The Hard Parts
JRuby: The Hard PartsJRuby: The Hard Parts
JRuby: The Hard Parts
 
tDiary annual report 2009 - Sapporo Ruby Kaigi02
tDiary annual report 2009 - Sapporo Ruby Kaigi02tDiary annual report 2009 - Sapporo Ruby Kaigi02
tDiary annual report 2009 - Sapporo Ruby Kaigi02
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mruby
 

Similar a Bringing Concurrency to Ruby - RubyConf India 2014

Actors and Threads
Actors and ThreadsActors and Threads
Actors and Threadsmperham
 
Ruby and Distributed Storage Systems
Ruby and Distributed Storage SystemsRuby and Distributed Storage Systems
Ruby and Distributed Storage SystemsSATOSHI TAGOMORI
 
Concurrency and Multithreading Demistified - Reversim Summit 2014
Concurrency and Multithreading Demistified - Reversim Summit 2014Concurrency and Multithreading Demistified - Reversim Summit 2014
Concurrency and Multithreading Demistified - Reversim Summit 2014Haim Yadid
 
ApacheCon2010: Cache & Concurrency Considerations in Cassandra (& limits of JVM)
ApacheCon2010: Cache & Concurrency Considerations in Cassandra (& limits of JVM)ApacheCon2010: Cache & Concurrency Considerations in Cassandra (& limits of JVM)
ApacheCon2010: Cache & Concurrency Considerations in Cassandra (& limits of JVM)srisatish ambati
 
The Why and How of Scala at Twitter
The Why and How of Scala at TwitterThe Why and How of Scala at Twitter
The Why and How of Scala at TwitterAlex Payne
 
Modern Java Concurrency (OSCON 2012)
Modern Java Concurrency (OSCON 2012)Modern Java Concurrency (OSCON 2012)
Modern Java Concurrency (OSCON 2012)Martijn Verburg
 
Evented Ruby VS Node.js
Evented Ruby VS Node.jsEvented Ruby VS Node.js
Evented Ruby VS Node.jsNitin Gupta
 
Storm presentation
Storm presentationStorm presentation
Storm presentationShyam Raj
 
Scalability, Availability & Stability Patterns
Scalability, Availability & Stability PatternsScalability, Availability & Stability Patterns
Scalability, Availability & Stability PatternsJonas Bonér
 
Chirp 2010: Scaling Twitter
Chirp 2010: Scaling TwitterChirp 2010: Scaling Twitter
Chirp 2010: Scaling TwitterJohn Adams
 
Performance and Abstractions
Performance and AbstractionsPerformance and Abstractions
Performance and AbstractionsMetosin Oy
 
Grand Central Dispatch and multi-threading [iCONdev 2014]
Grand Central Dispatch and multi-threading [iCONdev 2014]Grand Central Dispatch and multi-threading [iCONdev 2014]
Grand Central Dispatch and multi-threading [iCONdev 2014]Kuba Břečka
 
Ruby Concurrency Realities
Ruby Concurrency RealitiesRuby Concurrency Realities
Ruby Concurrency RealitiesMike Subelsky
 
Игорь Фесенко "Direction of C# as a High-Performance Language"
Игорь Фесенко "Direction of C# as a High-Performance Language"Игорь Фесенко "Direction of C# as a High-Performance Language"
Игорь Фесенко "Direction of C# as a High-Performance Language"Fwdays
 
Multithreading and Parallelism on iOS [MobOS 2013]
 Multithreading and Parallelism on iOS [MobOS 2013] Multithreading and Parallelism on iOS [MobOS 2013]
Multithreading and Parallelism on iOS [MobOS 2013]Kuba Břečka
 

Similar a Bringing Concurrency to Ruby - RubyConf India 2014 (20)

Actors and Threads
Actors and ThreadsActors and Threads
Actors and Threads
 
Ruby and Distributed Storage Systems
Ruby and Distributed Storage SystemsRuby and Distributed Storage Systems
Ruby and Distributed Storage Systems
 
Concurrency and Multithreading Demistified - Reversim Summit 2014
Concurrency and Multithreading Demistified - Reversim Summit 2014Concurrency and Multithreading Demistified - Reversim Summit 2014
Concurrency and Multithreading Demistified - Reversim Summit 2014
 
ApacheCon2010: Cache & Concurrency Considerations in Cassandra (& limits of JVM)
ApacheCon2010: Cache & Concurrency Considerations in Cassandra (& limits of JVM)ApacheCon2010: Cache & Concurrency Considerations in Cassandra (& limits of JVM)
ApacheCon2010: Cache & Concurrency Considerations in Cassandra (& limits of JVM)
 
The Why and How of Scala at Twitter
The Why and How of Scala at TwitterThe Why and How of Scala at Twitter
The Why and How of Scala at Twitter
 
Modern Java Concurrency (OSCON 2012)
Modern Java Concurrency (OSCON 2012)Modern Java Concurrency (OSCON 2012)
Modern Java Concurrency (OSCON 2012)
 
Evented Ruby VS Node.js
Evented Ruby VS Node.jsEvented Ruby VS Node.js
Evented Ruby VS Node.js
 
Performance
PerformancePerformance
Performance
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
Storm presentation
Storm presentationStorm presentation
Storm presentation
 
Ruby Concurrency
Ruby ConcurrencyRuby Concurrency
Ruby Concurrency
 
Why Play Framework is fast
Why Play Framework is fastWhy Play Framework is fast
Why Play Framework is fast
 
Scalability, Availability & Stability Patterns
Scalability, Availability & Stability PatternsScalability, Availability & Stability Patterns
Scalability, Availability & Stability Patterns
 
Chirp 2010: Scaling Twitter
Chirp 2010: Scaling TwitterChirp 2010: Scaling Twitter
Chirp 2010: Scaling Twitter
 
Why ruby and rails
Why ruby and railsWhy ruby and rails
Why ruby and rails
 
Performance and Abstractions
Performance and AbstractionsPerformance and Abstractions
Performance and Abstractions
 
Grand Central Dispatch and multi-threading [iCONdev 2014]
Grand Central Dispatch and multi-threading [iCONdev 2014]Grand Central Dispatch and multi-threading [iCONdev 2014]
Grand Central Dispatch and multi-threading [iCONdev 2014]
 
Ruby Concurrency Realities
Ruby Concurrency RealitiesRuby Concurrency Realities
Ruby Concurrency Realities
 
Игорь Фесенко "Direction of C# as a High-Performance Language"
Игорь Фесенко "Direction of C# as a High-Performance Language"Игорь Фесенко "Direction of C# as a High-Performance Language"
Игорь Фесенко "Direction of C# as a High-Performance Language"
 
Multithreading and Parallelism on iOS [MobOS 2013]
 Multithreading and Parallelism on iOS [MobOS 2013] Multithreading and Parallelism on iOS [MobOS 2013]
Multithreading and Parallelism on iOS [MobOS 2013]
 

Más de Charles Nutter

The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018Charles Nutter
 
Down the Rabbit Hole: An Adventure in JVM Wonderland
Down the Rabbit Hole: An Adventure in JVM WonderlandDown the Rabbit Hole: An Adventure in JVM Wonderland
Down the Rabbit Hole: An Adventure in JVM WonderlandCharles Nutter
 
Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016Charles Nutter
 
JRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVMJRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVMCharles Nutter
 
JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015Charles Nutter
 
JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015Charles Nutter
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaCharles Nutter
 
Open Source Software Needs You!
Open Source Software Needs You!Open Source Software Needs You!
Open Source Software Needs You!Charles Nutter
 
InvokeBinder: Fluent Programming for Method Handles
InvokeBinder: Fluent Programming for Method HandlesInvokeBinder: Fluent Programming for Method Handles
InvokeBinder: Fluent Programming for Method HandlesCharles Nutter
 
Over 9000: JRuby in 2015
Over 9000: JRuby in 2015Over 9000: JRuby in 2015
Over 9000: JRuby in 2015Charles Nutter
 
Doing Open Source the Right Way
Doing Open Source the Right WayDoing Open Source the Right Way
Doing Open Source the Right WayCharles Nutter
 
Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013Charles Nutter
 
Beyond JVM - YOW! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013Beyond JVM - YOW! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013Charles Nutter
 
Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013Charles Nutter
 
The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013Charles Nutter
 
High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013Charles Nutter
 
Invokedynamic in 45 Minutes
Invokedynamic in 45 MinutesInvokedynamic in 45 Minutes
Invokedynamic in 45 MinutesCharles Nutter
 
Invokedynamic: Tales from the Trenches
Invokedynamic: Tales from the TrenchesInvokedynamic: Tales from the Trenches
Invokedynamic: Tales from the TrenchesCharles Nutter
 
Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012Charles Nutter
 

Más de Charles Nutter (20)

The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018
 
Down the Rabbit Hole: An Adventure in JVM Wonderland
Down the Rabbit Hole: An Adventure in JVM WonderlandDown the Rabbit Hole: An Adventure in JVM Wonderland
Down the Rabbit Hole: An Adventure in JVM Wonderland
 
Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016
 
JRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVMJRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVM
 
JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015
 
JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible Java
 
Open Source Software Needs You!
Open Source Software Needs You!Open Source Software Needs You!
Open Source Software Needs You!
 
InvokeBinder: Fluent Programming for Method Handles
InvokeBinder: Fluent Programming for Method HandlesInvokeBinder: Fluent Programming for Method Handles
InvokeBinder: Fluent Programming for Method Handles
 
Over 9000: JRuby in 2015
Over 9000: JRuby in 2015Over 9000: JRuby in 2015
Over 9000: JRuby in 2015
 
Doing Open Source the Right Way
Doing Open Source the Right WayDoing Open Source the Right Way
Doing Open Source the Right Way
 
Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013
 
Beyond JVM - YOW! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013Beyond JVM - YOW! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013
 
Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013
 
Down the Rabbit Hole
Down the Rabbit HoleDown the Rabbit Hole
Down the Rabbit Hole
 
The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013
 
High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013
 
Invokedynamic in 45 Minutes
Invokedynamic in 45 MinutesInvokedynamic in 45 Minutes
Invokedynamic in 45 Minutes
 
Invokedynamic: Tales from the Trenches
Invokedynamic: Tales from the TrenchesInvokedynamic: Tales from the Trenches
Invokedynamic: Tales from the Trenches
 
Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012
 

Último

2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusZilliz
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 

Último (20)

2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 

Bringing Concurrency to Ruby - RubyConf India 2014

  • 1. Bringing Concurrency to Ruby Charles Oliver Nutter @headius
  • 2.
  • 3. Me, about 40 weeks of the year
  • 4. Me, the other 12 weeks of the year
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 12. Concurrency • Two or more jobs • Making progress • Over a given time span
  • 13. Parallelism • Two or more computations • Executing at the same moment in time
  • 14. Examples • Thread APIs: concurrency • Actore APIs: concurrency • Native thread, process: parallelism • If the underlying system supports it • SIMD, GPU, vector operations: parallelism
  • 15.
  • 16.
  • 17.
  • 18. You Need Both • Work that can split into concurrent jobs • Platform that runs those jobs in parallel • In an ideal world, scales with job count • In our world, each job adds overhead
  • 19. Process-level Concurrency • Separate processes running concurrently • As parallel as OS/CPU can make them • Low risk due to isolated memory space • High memory requirements • High communication overhead
  • 20. Thread-level Concurrency • Threads in-process running concurrently • As parallel as OS/CPU can make them • Higher risk due to shared memory space • Lower memory requirements • Low communication overhead
  • 21. Popular Platforms Concurrency Parallelism GC Notes MRI 1.8.7 ✔ ✘ Single thread, stop- the-world Large C core would need much work MRI 1.9+ ✔ ✘ Single thread, stop- the-world Few changes since 1.9.3 JRuby (JVM) ✔ ✔ Many concurrent and parallel options JVM is the “best” platform for conc Rubinius ✔ ✔ Single thread, stop- the-world, partial concurrent old gen Promising, but a long road ahead Topaz ✘ ✘ Single thread, stop- the-world Incomplete impl Node.js (V8) ✘ ✘ Single thread, stop- the-world No threads in JS CPython ✔ ✘ Reference-counting Reference counting kills parallelism Pypy ✔ ✘ Single thread, stop- the-world Exploring STM to enable concurrency
  • 23.
  • 24. MRI 1.8.7, One Thread
  • 25. MRI 1.8.7, Eight Threads
  • 26. Timeslicing Thread 1 Thread 2 Thread 3 Thread 4 Native thread Native thread Native thread Native thread “Green” or “virtual” or “userspace” threads share a single native thread.The CPU then schedules that thread on available CPUs. Time’s up Time’s up Time’s up
  • 27. MRI 1.8.7, Eight Threads
  • 28. MRI 1.9.3+, Eight Threads
  • 29. GVL: GlobalVM Lock Thread 1 Thread 2 Thread 3 Thread 4 CPU CPU CPU CPU In 1.9+, each thread gets its own native thread, but a global lock prevents concurrent execution. Time slices are finer grained and variable, but threads still can’t run in parallel. Lock xfer CPU Lock xfer Lock xfer
  • 31. MRI 1.9.3+, Eight Threads
  • 32. MRI 1.9.3+, Eight Threads
  • 34. Why Do We See Parallelism? • Hotspot JVM has many background threads • GC with concurrent and parallel options • JIT threads • Signal handling • Monitoring and management
  • 37. Time Matters Too 0 1.75 3.5 5.25 7 Time per iteration MRI 1.8.7 MRI 1.9.3 JRuby Nearly 10x faster than 1.9.3
  • 38. Rules of Concurrency 1. Don’t do it, if you don’t have to. 2. If you must do it, don’t share data. 3. If you must share data, make it immutable. 4. If it must be mutable, coordinate all access.
  • 39. #1: Don’t • Many problems won’t benefit • Explicitly sequential things, e.g • Bad code can get worse • Multiply perf, GC, alloc overhead by N • Fixes may not be easy (esp. in Ruby) • The risks can get tricky to address
  • 40.
  • 41.
  • 42.
  • 43.
  • 44. I’m Not Perfect • Wrote a naive algorithm • Measured it taking N seconds • Wrote the concurrent version • Measured it taking roughly N seconds • Returned to original to optimize
  • 45. Fix Single-thread First!Timeinseconds 0 5 10 15 20 big_list time v1 v2 v3 v4 String slice instead of unpack/pack Simpler loops Stream from file
  • 46. Timeinseconds 0 17.5 35 52.5 70 Processing 23M word file Non-threaded Two threads Four threads
  • 47. Before Conc Work • Fix excessive allocation (and GC) • Fix algorithmic complexity • Test on the runtime you want to target • If serial perf is still poor after optimization, the task, runtime, or system may not be appropriate for a concurrent version.
  • 48. Concurrency won’t help code that’s using up all hardware resources.
  • 49. #2: Don’t Share Data • Process-level concurrency • …have to sync up eventually, though • Threads with their own data objects • Rails request objects, e.g. • APIs with a “master” object, usually • Weakest form of concurrency
  • 50. #3: Immutable Data • In other words… • Data can be shared • Threads can pass it around safely • Cross-thread view of data can’t mutate • Threads can’t see concurrent mutations as they happen, avoiding data races
  • 51. Object#freeze • Simplest mechanism for immutability • For read-only: make changes, freeze • Read-mostly: dup, change, freeze, replace • Write-mostly: same, but O(n) complexity
  • 52. Immutable Data Structure • Designed to avoid visible mutation but still have good performance characteristics • Copy-on-write is poor-man’s IDS • Better: persistent data structures like Ctrie http://en.wikipedia.org/wiki/Ctrie
  • 53. Persistent? • Collection you have a reference to is guaranteed never to change • Modifications return a new reference • …and only duplicate affected part of trie
  • 54. Hamster • Pure-Ruby persistent data structures • Set, List, Stack, Queue,Vector, Hash • Based on Clojure’s Ctrie collections • https://github.com/hamstergem/hamster
  • 55. person = Hamster.hash(! :name => “Simon",! :gender => :male)! # => {:name => "Simon", :gender => :male}!  ! person[:name]! # => "Simon"! person.get(:gender)! # => :male!  ! friend = person.put(:name, "James")! # => {:name => "James", :gender => :male}! person! # => {:name => "Simon", :gender => :male}! friend[:name]! # => "James"! person[:name]! # => "Simon"
  • 56. Coming Soon • Reimplementation by Smit Shah • Mostly “native” impl of Ctrie • Considerably better perf than Hamster • https://github.com/Who828/persistent_data_structures
  • 57. Other Techniques • Known-immutable data like Symbol, Fixnum • Mutate for a while, then freeze • Hand-off: if you pass mutable data, assume you can’t mutate it anymore • Sometimes enforced by runtime, e.g. “thread-owned objects”
  • 58. #4: Synchronize Mutation • Trickiest to get right; usually best perf • Fully-immutable generates lots of garbage • Locks, atomics, and specialized collections
  • 59. Locks • Avoid concurrent operations • Read + write, in general • Many varieties: reentrant, read/write • Many implementations
  • 60. Mutex • Simplest form of lock • Acquire, do work, release • Not reentrant semaphore = Mutex.new! ...! a = Thread.new {! semaphore.synchronize {! # access shared resource! }! }
  • 61. ConditionVariable • Release mutex temporarily • Signal others waiting on the mutex • …and be signaled • Similar to wait/notify/notifyAll in Java
  • 62. resource = ConditionVariable.new!  ! a = Thread.new {! mutex.synchronize {! # Thread 'a' now needs the resource! resource.wait(mutex)! # 'a' can now have the resource! }! }!  ! b = Thread.new {! mutex.synchronize {! # Thread 'b' has finished using the resource! resource.signal! }! }!
  • 63. Monitor • Reentrancy • “try” acquire • Mix-in for convenience • Java synchronization = CondVar + Monitor
  • 64. Monitor require 'monitor'!  ! lock = Monitor.new! lock.synchronize do! # exclusive access! end
  • 65. Monitor require 'monitor'!  ! class SynchronizedArray < Array!  ! include MonitorMixin!  ! alias :old_shift :shift!  ! def shift(n=1)! self.synchronize do! self.old_shift(n)! end! end! ...
  • 66. Atomics • Without locking… • …replace a value only if unchanged • …increment, decrement safely • Thread-safe code can use atomics instead of locks, usually with better performance
  • 67. atomic • Atomic operations for Ruby • https://github.com/headius/ruby-atomic
  • 68. require 'atomic'!  ! my_atomic = Atomic.new(0)! my_atomic.value! # => 0! my_atomic.value = 1! my_atomic.swap(2)! # => 1! my_atomic.compare_and_swap(2, 3)! # => true, updated to 3! my_atomic.compare_and_swap(2, 3)! # => false, current is not 2
  • 69. Specialized Collections • thread_safe gem • Fully-synchronized Array and Hash • Atomic-based hash impl (“Cache”) • java.util.concurrent • Numerous tools for concurrency
  • 70. Queues • Thread-safe Queue and SizedQueue • Pipeline data to/from threads • Standard in all Ruby impls
  • 71. thread_count = (ARGV[2] || 1).to_i! queue = SizedQueue.new(thread_count * 4)! ! word_file.each_line.each_slice(50) do |words|! queue << words! end! queue << nil # terminating condition
  • 72. threads = thread_count.times.map do |i|! Thread.new do! while true! words = queue.pop! if words.nil? # terminating condition! queue.shutdown! break! end! words.each do |word|! # analyze the word
  • 73. Putting It All Together • These are a lot of tools to sort out • Others have sorted them out for you
  • 74. Celluloid • Actor model implementation • OO/Ruby sensibilities • Normal classes, normal method calls • Async support • Growing ecosystem • Celluloid-IO and DCell (distributed actors) • https://github.com/celluloid/celluloid
  • 75. class Sheen! include Celluloid!  ! def initialize(name)! @name = name! end!  ! def set_status(status)! @status = status! end!  ! def report! "#{@name} is #{@status}"! end! end
  • 76. >> charlie = Sheen.new "Charlie Sheen"! => #<Celluloid::Actor(Sheen:0x00000100a312d0) @name="Char >> charlie.set_status "winning!"! => "winning!"! >> charlie.report! => "Charlie Sheen is winning!"! >> charlie.async.set_status "asynchronously winning!"! => nil! >> charlie.report! => "Charlie Sheen is asynchronously winning!"
  • 77. Sidekiq • Simple, efficient background processing • Think Resque or DelayedJob but better • Normal-looking Ruby class is the job • Simple call to start it running in background • http://mperham.github.io/sidekiq/
  • 78. class HardWorker! include Sidekiq::Worker!  ! def perform(name, count)! puts 'Doing hard work'! end! end! ! ...later, in a controller...!  ! HardWorker.perform_async('bob', 5)
  • 79. Concurrent Ruby • Grab bag of concurrency patterns • Actor,Agent, Channel, Future, Promise, ScheduledTask,TimerTask, Supervisor • Thread pools, executors, timeouts, conditions, latches, atomics • May grow into a central lib for conc stuff • https://github.com/jdantonio/concurrent-ruby
  • 80. …all the examples I’ve shown you and more
  • 81. Recap • The future of Ruby is concurrent • The tools are there to help you • Let’s all help move Ruby forward
  • 82. Thank you! • Charles Oliver Nutter • headius@headius.com • @headius