SlideShare una empresa de Scribd logo
1 de 101
High Performance Ruby
Tips,Techniques, and Futures
Monday, July 1, 13
Me
• Charles Oliver Nutter
• @headius
• Java developer since 1996
• JRuby developer since 2006
• Red Hat / JBoss polyglot group
Monday, July 1, 13
Is Ruby fast?
Monday, July 1, 13
Is Ruby fast enough?
Monday, July 1, 13
How fast do you need
Ruby to be?
Monday, July 1, 13
What Should We
Optimize?
• Overall execution time?
• Memory use?
• Developer time?
• Developer happiness? :-)
Monday, July 1, 13
Ruby can be fast...
if you know how.
Monday, July 1, 13
Strategies
• Use a better runtime
• Use more cores
• Write better code
Monday, July 1, 13
Use a BetterVM
Monday, July 1, 13
Many Options
• Ruby 2.0
• Significant execution improvements
• JRuby
• Leveraging JVM more and more
• Rubinius
• OptimizingVM built for Ruby
Monday, July 1, 13
0
7.5
15
22.5
30
Java 1.4 Java 5 Java 6 Java 7
Go Java Go!
JRuby 1.0.3 (bm_red_black_tree.rb)
300% for free
Monday, July 1, 13
0
2
4
6
8
1.0.3 1.1.6 1.4.0 1.5.6 1.6.8 1.7.0
OpenJDK 8 (bm_red_black_tree.rb)
Go JRuby Go!
8.2x Improvement
Monday, July 1, 13
rbtree Extension
• Pure Ruby version works everywhere
• C or Java extension FOR SPEED
• Oh really? ;-)
Monday, July 1, 13
Monday, July 1, 13
0 1 2 3 4
ruby-1.9.3 + Ruby
ruby-2.0.0 + Ruby
maglev + Ruby
macruby-0.12 + Ruby
rbx-2.0.0rc1 + Ruby
ruby-1.9.3 + C ext
ruby-2.0.0 + C ext
jruby + Ruby
jruby + Java ext
red/black tree, pure Ruby versus native
Runtime per iteration
Monday, July 1, 13
0 1 2 3 4
ruby-1.9.3 + Ruby
ruby-2.0.0 + Ruby
maglev + Ruby
macruby-0.12 + Ruby
rbx-2.0.0rc1 + Ruby
ruby-1.9.3 + C ext
ruby-2.0.0 + C ext
jruby + Ruby
jruby + Java ext
3.96
red/black tree, pure Ruby versus native
Runtime per iteration
Monday, July 1, 13
0 1 2 3 4
ruby-1.9.3 + Ruby
ruby-2.0.0 + Ruby
maglev + Ruby
macruby-0.12 + Ruby
rbx-2.0.0rc1 + Ruby
ruby-1.9.3 + C ext
ruby-2.0.0 + C ext
jruby + Ruby
jruby + Java ext
3.96
2.48
red/black tree, pure Ruby versus native
Runtime per iteration
Monday, July 1, 13
0 1 2 3 4
ruby-1.9.3 + Ruby
ruby-2.0.0 + Ruby
maglev + Ruby
macruby-0.12 + Ruby
rbx-2.0.0rc1 + Ruby
ruby-1.9.3 + C ext
ruby-2.0.0 + C ext
jruby + Ruby
jruby + Java ext
3.96
2.48
1.39
red/black tree, pure Ruby versus native
Runtime per iteration
Monday, July 1, 13
0 1 2 3 4
ruby-1.9.3 + Ruby
ruby-2.0.0 + Ruby
maglev + Ruby
macruby-0.12 + Ruby
rbx-2.0.0rc1 + Ruby
ruby-1.9.3 + C ext
ruby-2.0.0 + C ext
jruby + Ruby
jruby + Java ext
3.96
2.48
1.39
1.19
red/black tree, pure Ruby versus native
Runtime per iteration
Monday, July 1, 13
0 1 2 3 4
ruby-1.9.3 + Ruby
ruby-2.0.0 + Ruby
maglev + Ruby
macruby-0.12 + Ruby
rbx-2.0.0rc1 + Ruby
ruby-1.9.3 + C ext
ruby-2.0.0 + C ext
jruby + Ruby
jruby + Java ext
3.96
2.48
1.39
1.19
0.51
red/black tree, pure Ruby versus native
Runtime per iteration
Monday, July 1, 13
0 1 2 3 4
ruby-1.9.3 + Ruby
ruby-2.0.0 + Ruby
maglev + Ruby
macruby-0.12 + Ruby
rbx-2.0.0rc1 + Ruby
ruby-1.9.3 + C ext
ruby-2.0.0 + C ext
jruby + Ruby
jruby + Java ext
3.96
2.48
1.39
1.19
0.51
0.51
red/black tree, pure Ruby versus native
Runtime per iteration
Monday, July 1, 13
0 1 2 3 4
ruby-1.9.3 + Ruby
ruby-2.0.0 + Ruby
maglev + Ruby
macruby-0.12 + Ruby
rbx-2.0.0rc1 + Ruby
ruby-1.9.3 + C ext
ruby-2.0.0 + C ext
jruby + Ruby
jruby + Java ext
3.96
2.48
1.39
1.19
0.51
0.51
0.51
red/black tree, pure Ruby versus native
Runtime per iteration
Monday, July 1, 13
0 1 2 3 4
ruby-1.9.3 + Ruby
ruby-2.0.0 + Ruby
maglev + Ruby
macruby-0.12 + Ruby
rbx-2.0.0rc1 + Ruby
ruby-1.9.3 + C ext
ruby-2.0.0 + C ext
jruby + Ruby
jruby + Java ext
3.96
2.48
1.39
1.19
0.51
0.51
0.51
0.29
red/black tree, pure Ruby versus native
Runtime per iteration
Monday, July 1, 13
0 1 2 3 4
ruby-1.9.3 + Ruby
ruby-2.0.0 + Ruby
maglev + Ruby
macruby-0.12 + Ruby
rbx-2.0.0rc1 + Ruby
ruby-1.9.3 + C ext
ruby-2.0.0 + C ext
jruby + Ruby
jruby + Java ext
3.96
2.48
1.39
1.19
0.51
0.51
0.51
0.29
0.1
red/black tree, pure Ruby versus native
Runtime per iteration
Monday, July 1, 13
But How?
Monday, July 1, 13
Dynamic Optimization
• Target method/value discovered at runtime
• Lookup is expensive
• We can cache it
• Cache has to be validated
• Indirection hurts pipeline
• Inline methods/values at access point
Monday, July 1, 13
Method Caching
Target
Object
FooClass
def foo ...
def bar ...
associated with
obj.foo() VM
method table
Monday, July 1, 13
VM Operations
Method Caching
Target
Object
FooClass
def foo ...
def bar ...
associated with
obj.foo() VM
Call Site
method table
Monday, July 1, 13
VM Operations
Method Lookup
Method Caching
Target
Object
FooClass
def foo ...
def bar ...
associated with
obj.foo() VM
Call Site
method table
Monday, July 1, 13
VM Operations
Method Lookup
Method Caching
Target
Object
FooClass
def foo ...
def bar ...
associated with
obj.foo() VM
def foo ...
Call Site
method table
Monday, July 1, 13
VM Operations
Method Lookup
Branch
Method Caching
Target
Object
FooClass
def foo ...
def bar ...
associated with
obj.foo() VM
def foo ...
Call Site
method table
Monday, July 1, 13
VM Operations
Method Lookup
Branch
Method Cache
Method Caching
Target
Object
FooClass
def foo ...
def bar ...
associated with
obj.foo() VM
def foo ...
Call Site
method table
Monday, July 1, 13
Constant Lookup
Constant
Table
MY_CONST VM
Monday, July 1, 13
VM Operations
Constant Lookup
Constant
Table
MY_CONST VM
Access Site
Monday, July 1, 13
VM Operations
LocateValue
Constant Lookup
Constant
Table
MY_CONST VM
Access Site
value
Monday, July 1, 13
VM Operations
LocateValue
Bind Permanently
Constant Lookup
Constant
Table
MY_CONST VM
Access Site
value
Monday, July 1, 13
def foo; 1; end
def invoker; foo; end
i = 0
while i < 10000
  invoker
  i+=1
end
Inlining
Monday, July 1, 13
def invoker; 1; end
i = 0
while i < 10000
  invoker
  i+=1
end
Inline foo into invoker
Monday, July 1, 13
i = 0
while i < 10000
  1
  i+=1
end
Inline invoker into loop
Monday, July 1, 13
i = 0
while i < 10000
  i+=1
end
Value is transient
Monday, July 1, 13
i = 10000
Loop does nothing
Monday, July 1, 13
Variable i is never read
Monday, July 1, 13
Use More Cores
Monday, July 1, 13
It's a multi-core world
• Scaling today is horizontal, not vertical
• N processes does not cut it
• N users * X MB process = $$$
• CoW is only a partial band-aid
• Non-parallel impls are falling behind
• JRuby, Rubinius your only real options
Monday, July 1, 13
True Parallellism
Ruby
Threads
Native
Threads
CPU Cores
in Use
Monday, July 1, 13
True Parallellism
Ruby
Threads
Native
Threads
Ruby 1.8.7
Green Threading
CPU Cores
in Use
Single Thread
Monday, July 1, 13
True Parallellism
Ruby
Threads
Native
Threads
Ruby 1.8.7 Ruby 2.0.0
Green Threading
CPU Cores
in Use
Global LockSingle Thread
Monday, July 1, 13
True Parallellism
Ruby
Threads
Native
Threads
Ruby 1.8.7 Ruby 2.0.0
Green Threading
CPU Cores
in Use
JRuby
Global LockSingle Thread Real Threading
Monday, July 1, 13
Multicore in MRI
200MB MRI
Instance
200MB MRI
Instance
200MB MRI
Instance
200MB MRI
Instance
200MB MRI
Instance
200MB MRI
Instance
200MB MRI
Instance
200MB MRI
Instance
200MB MRI
Instance
200MB MRI
Instance
200MB MRI
Instance
Ten instances * 200MB = 2GB
Monday, July 1, 13
Multicore in JRuby
300MB JRuby
Instance
One instance across 10 threads = 300MB
Monday, July 1, 13
require 'benchmark'
ary = (1..1000000).to_a
loop {
  puts Benchmark.measure {
    10.times {
      ary.each {|i|}
    }
  }
}
Monday, July 1, 13
require 'benchmark'
ary = (1..1000000).to_a
loop {
  puts Benchmark.measure {
    (1..10).map {
      Thread.new {
        ary.each {|i|}
      }
    }.map(&:join)
  }
}
Monday, July 1, 13
Monday, July 1, 13
Ruby 1.9
single thread
JRuby
single thread
Monday, July 1, 13
Ruby 1.9
single thread
Ruby 1.9
multiple threads
JRuby
single thread
JRuby
multiple threads
Monday, July 1, 13
0.2s
0.35s
0.5s
0.65s
0.8s
one thread two threads three threads four threads
Per-iteration time versus thread count
threaded_reverse
Monday, July 1, 13
Doing It Right
• Lock-free persistent data structures
• hamster et al
• Thread-safety utilities
• Mutex, Queue, thread_safe + atomic gems
• Threaded servers
• puma, trinidad, torquebox, JVM servers
Monday, July 1, 13
Finding Problems
• JRuby
• VM flags (heap/thread dumps, debug)
• Some of the best tools in the world
• Rubinius
• gdb, OS-level tools
• #rubinius
Monday, July 1, 13
Write Better Code
Monday, July 1, 13
• eval
• Exceptions as flow control
• Excessive allocation
• Defeating optimizations
• IO, DB, bad libraries
• VM flaw*
Usual Suspects
*I usually assume it's JRuby's fault until proven otherwise
Monday, July 1, 13
eval
• Code never stays the same
• VM can't cache, can't see patterns
• No optimization is possible*
*Specific cases can sometimes be cached and optimized
Monday, July 1, 13
Fixing eval
• Evaluate code into a method and leave it
• Methods are stable, optimizable
• Pass dynamic state, rather than interpolate
• Branches are cheaper than new code
• Do all evaluation up front
• ...not during your app's hot path
Monday, July 1, 13
Exceptions
• Act like a special return value
• Construct object with information
• Capture call stack at raise point
• Unroll call stack until rescued
• Overhead ranges from big to huge
• Especially costly on optimizingVMs
Monday, July 1, 13
def foo(a); raise; rescue; return a + 1; end
Shallow stack, 100k calls:
JRuby w/ exception: 7.7s
JRuby w/o exception: 0.004s
Ruby 2 w/ exception: 0.25s
Ruby 2 w/o exception: 0.009s
Rubinius w/ exception: 0.1s
Rubinius w/o exception: 0.002s
Monday, July 1, 13
def foo(a); raise; rescue; return a + 1; end
Deep stack, 100k calls:
JRuby w/ exception: 200s
Ruby 2 w/ exception: 1.25s
Rubinius w/ exception: 7.7s
Monday, July 1, 13
Exception Alternatives
• Pre-allocated exception object
• Empty backtrace passed to raise()
• Special return value
• Check at each caller
• catch/throw
• Avoids most overhead
Monday, July 1, 13
Allocation
• Literals
• "foo" creates object every time
• String + String,Array + Array
• Creates intermediate objects
• += is especially wasteful
• Slicing and enumerating
• ary.map{}.select{}.inject{}.find = 3 arrays
Monday, July 1, 13
Fixing Literals
• Constants are your friends
• Optimizes well on most impls
• Avoids literal churn
• Cache common interpolated values
• Study memory profiles
Monday, July 1, 13
Fixing Concat/Copy
• Modify in place
• Thread-safety trade-offs...
• Use persistent structures
• "hamster" gem
• Google "immutable ruby"
Monday, July 1, 13
Fixing Enum Chaining
• Condense into fewer steps
• Lazy Enumerator in 2.0
• Just use a loop :-)
Monday, July 1, 13
Defeating Optimization
• Caching and inlining are key to perf
• If we can't cache...
• Methods won't inline, won't optimize
• Constants must be looked up every time
• We have less time for real work
Monday, July 1, 13
Method Cache Busting
• VM must ensure cache is correct
• Check type
• Ensure method table is the same
• New type every time? No caching.
• Modify method table? No caching.
Monday, July 1, 13
VM Operations
Method Lookup
Branch
Method Cache
Dynamic Invocation
Target
Object
FooClass
def foo ...
def bar ...
associated with
obj.foo() VM
Call Site
method table
Monday, July 1, 13
VM Operations
Method Lookup
Branch
Method Cache
Dynamic Invocation
Target
Object
FooClass
def foo ...
def bar ...
associated with
obj.foo() VM
def foo ...
Call Site
method table
Monday, July 1, 13
VM Operations
Method Lookup
Branch
Method Cache
Dynamic Invocation
Target
Object
FooClass
def foo ...
def bar ...
associated with
obj.foo() VM
Call Site
method table
Monday, July 1, 13
VM Operations
Method Lookup
Branch
Method Cache
Dynamic Invocation
Target
Object
FooClass
def foo ...
def bar ...
associated with
obj.foo() VM
def foo ...
Call Site
method table
Monday, July 1, 13
VM Operations
Method Lookup
Branch
Method Cache
Dynamic Invocation
Target
Object
FooClass
def foo ...
def bar ...
associated with
obj.foo() VM
Call Site
method table
Monday, July 1, 13
VM Operations
Method Lookup
Branch
Method Cache
Dynamic Invocation
Target
Object
FooClass
def foo ...
def bar ...
associated with
obj.foo() VM
def foo ...
Call Site
method table
Monday, July 1, 13
VM Operations
Method Lookup
Branch
Method Cache
Dynamic Invocation
Target
Object
FooClass
def foo ...
def bar ...
associated with
obj.foo() VM
Call Site
method table
Monday, July 1, 13
VM Operations
Method Lookup
Branch
Method Cache
Dynamic Invocation
Target
Object
FooClass
def foo ...
def bar ...
associated with
obj.foo() VM
def foo ...
Call Site
method table
Monday, July 1, 13
VM Operations
Method Lookup
Branch
Method Cache
Dynamic Invocation
Target
Object
FooClass
def foo ...
def bar ...
associated with
obj.foo() VM
Call Site
method table
Monday, July 1, 13
VM Operations
Method Lookup
Branch
Method Cache
Dynamic Invocation
Target
Object
FooClass
def foo ...
def bar ...
associated with
obj.foo() VM
def foo ...
Call Site
method table
Monday, July 1, 13
Singletons
• Creates new types at runtime
• Impossible to cache based on type
• Usually defines new methods
• Method table is always different
class << foo ...
def foo.bar ...
Monday, July 1, 13
Object#extend
• Includes module into single object
• New one-off type every time
• Class hierarchy keeps changing
foo.extend Enumerable
Monday, July 1, 13
static VALUE
io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock)
{
...
n = rb_read_internal(fptr->fd, RSTRING_PTR(str), len);
rb_str_unlocktmp(str);
if (n < 0) {
if (!nonblock && rb_io_wait_readable(fptr->fd))
goto again;
if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
rb_mod_sys_fail(rb_mWaitReadable, "read would block");
rb_sys_fail_path(fptr->pathv);
}
...
}
Monday, July 1, 13
static VALUE
io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock)
{
...
n = rb_read_internal(fptr->fd, RSTRING_PTR(str), len);
rb_str_unlocktmp(str);
if (n < 0) {
if (!nonblock && rb_io_wait_readable(fptr->fd))
goto again;
if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
rb_mod_sys_fail(rb_mWaitReadable, "read would block");
rb_sys_fail_path(fptr->pathv);
}
...
}
Monday, July 1, 13
void
rb_mod_sys_fail(VALUE mod, const char *mesg)
{
VALUE exc = make_errno_exc(mesg);
rb_extend_object(exc, mod);
rb_exc_raise(exc);
}
Monday, July 1, 13
void
rb_mod_sys_fail(VALUE mod, const char *mesg)
{
VALUE exc = make_errno_exc(mesg);
rb_extend_object(exc, mod);
rb_exc_raise(exc);
}
Monday, July 1, 13
Fixing Singletons/
#extend
• Functional patterns
• FooLibrary.process(obj) rather than
obj.extend FooLibrary; obj.process
• Create types up front (programmatically?)
• 1000 predefined types beats infinite types
Monday, July 1, 13
Monday, July 1, 13
Monday, July 1, 13
Constant Lookup
• Constants in tables on classes/modules
• Usually assigned only once, at load time
• Lookup is expensive, like methods
• Values can be cached
Monday, July 1, 13
Constant Cache
• Constant search proceeds two ways
• First, lexical scoping
• Second, class hierarchy
• Invalidation happens globally
Monday, July 1, 13
Constant Cache Busting
• Redefining constants
• Introducing new lexical scopes
• Classes created at runtime
• Evaluated code
• Altering class hierarchies
• Lookup results may change...no caching
Monday, July 1, 13
Fixing Constants
• Don't modify them
• i.e. CONSTANT
• Avoid runtime class hierarchy changes
Monday, July 1, 13
How to Get Help
Monday, July 1, 13
Performance Issues
• Assume nothing...most can be fixed
• Isolate bad code, small a case as possible
• UseVM tools to monitor caches
• Fix if it's your bug, PR if it's a library
• Come to us for help or if it's aVM bug
• Repeat...
Monday, July 1, 13
Concurrency Issues
• Avoid mutable state
• Synchronize mutations
• Start coarse-grained, get finer over time
• VM tooling to monitor locks, contention
• ContactVM authors for help
Monday, July 1, 13
Monday, July 1, 13
Ruby can be fast...and
we want to help you.
Monday, July 1, 13
ThankYou!
• Charles Oliver Nutter
• @headius
• http://jruby.org
• http://blog.headius.com
• Book: "Using JRuby"
• Book: "Deploying JRuby"
Monday, July 1, 13

Más contenido relacionado

La actualidad más candente

Roadmap for RubyGems 4 and Bundler 3
Roadmap for RubyGems 4 and Bundler 3Roadmap for RubyGems 4 and Bundler 3
Roadmap for RubyGems 4 and Bundler 3Hiroshi SHIBATA
 
Building Ruby in Smalltalk
Building Ruby in SmalltalkBuilding Ruby in Smalltalk
Building Ruby in SmalltalkESUG
 
How to distribute Ruby to the world
How to distribute Ruby to the worldHow to distribute Ruby to the world
How to distribute Ruby to the worldHiroshi SHIBATA
 
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
 
Optcarrot: A Pure-Ruby NES Emulator
Optcarrot: A Pure-Ruby NES EmulatorOptcarrot: A Pure-Ruby NES Emulator
Optcarrot: A Pure-Ruby NES Emulatormametter
 
JRuby: Pushing the Java Platform Further
JRuby: Pushing the Java Platform FurtherJRuby: Pushing the Java Platform Further
JRuby: Pushing the Java Platform FurtherCharles Nutter
 
Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0Hiroshi SHIBATA
 
Java tuning on GNU/Linux for busy dev
Java tuning on GNU/Linux for busy devJava tuning on GNU/Linux for busy dev
Java tuning on GNU/Linux for busy devTomek Borek
 
TRICK2013 Results
TRICK2013 ResultsTRICK2013 Results
TRICK2013 Resultsmametter
 
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
 
The Future of library dependency manageement of Ruby
The Future of library dependency manageement of RubyThe Future of library dependency manageement of Ruby
The Future of library dependency manageement of RubyHiroshi SHIBATA
 
Bringing Concurrency to Ruby - RubyConf India 2014
Bringing Concurrency to Ruby - RubyConf India 2014Bringing Concurrency to Ruby - RubyConf India 2014
Bringing Concurrency to Ruby - RubyConf India 2014Charles Nutter
 
How to distribute Ruby to the world
How to distribute Ruby to the worldHow to distribute Ruby to the world
How to distribute Ruby to the worldHiroshi SHIBATA
 
Jvm tuning in a rush! - Lviv JUG
Jvm tuning in a rush! - Lviv JUGJvm tuning in a rush! - Lviv JUG
Jvm tuning in a rush! - Lviv JUGTomek Borek
 
20140425 ruby conftaiwan2014
20140425 ruby conftaiwan201420140425 ruby conftaiwan2014
20140425 ruby conftaiwan2014Hiroshi SHIBATA
 
Ruby Security the Hard Way
Ruby Security the Hard WayRuby Security the Hard Way
Ruby Security the Hard WayHiroshi SHIBATA
 
20140419 oedo rubykaigi04
20140419 oedo rubykaigi0420140419 oedo rubykaigi04
20140419 oedo rubykaigi04Hiroshi SHIBATA
 

La actualidad más candente (20)

近未来的並列 LL
近未来的並列 LL近未来的並列 LL
近未来的並列 LL
 
Roadmap for RubyGems 4 and Bundler 3
Roadmap for RubyGems 4 and Bundler 3Roadmap for RubyGems 4 and Bundler 3
Roadmap for RubyGems 4 and Bundler 3
 
Building Ruby in Smalltalk
Building Ruby in SmalltalkBuilding Ruby in Smalltalk
Building Ruby in Smalltalk
 
How to distribute Ruby to the world
How to distribute Ruby to the worldHow to distribute Ruby to the world
How to distribute Ruby to the world
 
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?
 
Optcarrot: A Pure-Ruby NES Emulator
Optcarrot: A Pure-Ruby NES EmulatorOptcarrot: A Pure-Ruby NES Emulator
Optcarrot: A Pure-Ruby NES Emulator
 
JRuby: Pushing the Java Platform Further
JRuby: Pushing the Java Platform FurtherJRuby: Pushing the Java Platform Further
JRuby: Pushing the Java Platform Further
 
Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0
 
Gems on Ruby
Gems on RubyGems on Ruby
Gems on Ruby
 
Java tuning on GNU/Linux for busy dev
Java tuning on GNU/Linux for busy devJava tuning on GNU/Linux for busy dev
Java tuning on GNU/Linux for busy dev
 
TRICK2013 Results
TRICK2013 ResultsTRICK2013 Results
TRICK2013 Results
 
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
 
The Future of library dependency manageement of Ruby
The Future of library dependency manageement of RubyThe Future of library dependency manageement of Ruby
The Future of library dependency manageement of Ruby
 
Bringing Concurrency to Ruby - RubyConf India 2014
Bringing Concurrency to Ruby - RubyConf India 2014Bringing Concurrency to Ruby - RubyConf India 2014
Bringing Concurrency to Ruby - RubyConf India 2014
 
How to distribute Ruby to the world
How to distribute Ruby to the worldHow to distribute Ruby to the world
How to distribute Ruby to the world
 
What's new in RubyGems3
What's new in RubyGems3What's new in RubyGems3
What's new in RubyGems3
 
Jvm tuning in a rush! - Lviv JUG
Jvm tuning in a rush! - Lviv JUGJvm tuning in a rush! - Lviv JUG
Jvm tuning in a rush! - Lviv JUG
 
20140425 ruby conftaiwan2014
20140425 ruby conftaiwan201420140425 ruby conftaiwan2014
20140425 ruby conftaiwan2014
 
Ruby Security the Hard Way
Ruby Security the Hard WayRuby Security the Hard Way
Ruby Security the Hard Way
 
20140419 oedo rubykaigi04
20140419 oedo rubykaigi0420140419 oedo rubykaigi04
20140419 oedo rubykaigi04
 

Similar a High Performance Ruby - E4E Conference 2013

The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013Charles Nutter
 
Exploring Ruby on Rails and PostgreSQL
Exploring Ruby on Rails and PostgreSQLExploring Ruby on Rails and PostgreSQL
Exploring Ruby on Rails and PostgreSQLBarry Jones
 
JRuby Hot Topics 2008-12-12
JRuby Hot Topics 2008-12-12JRuby Hot Topics 2008-12-12
JRuby Hot Topics 2008-12-12Koichiro Ohba
 
Yet Another Replication Tool: RubyRep
Yet Another Replication Tool: RubyRepYet Another Replication Tool: RubyRep
Yet Another Replication Tool: RubyRepDenish Patel
 
JRuby - The Best of Java and Ruby
JRuby - The Best of Java and RubyJRuby - The Best of Java and Ruby
JRuby - The Best of Java and RubyEvgeny Rahman
 
Rails performance at Justin.tv - Guillaume Luccisano
Rails performance at Justin.tv - Guillaume LuccisanoRails performance at Justin.tv - Guillaume Luccisano
Rails performance at Justin.tv - Guillaume LuccisanoGuillaume Luccisano
 
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
 
Adventures of java developer in ruby world
Adventures of java developer in ruby worldAdventures of java developer in ruby world
Adventures of java developer in ruby worldOrest Ivasiv
 
Introduction to Go
Introduction to GoIntroduction to Go
Introduction to Gozhubert
 
Rubymotion trip to inspect 2013
Rubymotion trip to inspect 2013Rubymotion trip to inspect 2013
Rubymotion trip to inspect 2013Hussein Morsy
 
Seattlerb why jruby
Seattlerb why jrubySeattlerb why jruby
Seattlerb why jrubysnacktime
 
Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0Hiroshi SHIBATA
 
The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018Charles Nutter
 
The story of language development
The story of language developmentThe story of language development
The story of language developmentHiroshi SHIBATA
 
node.js in action
node.js in actionnode.js in action
node.js in actionKaran Misra
 
GitHub Notable OSS Project
GitHub  Notable OSS ProjectGitHub  Notable OSS Project
GitHub Notable OSS Projectroumia
 
The Future of library dependency management of Ruby
 The Future of library dependency management of Ruby The Future of library dependency management of Ruby
The Future of library dependency management of RubyHiroshi SHIBATA
 

Similar a High Performance Ruby - E4E Conference 2013 (20)

The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013
 
Debugging rails
Debugging railsDebugging rails
Debugging rails
 
Exploring Ruby on Rails and PostgreSQL
Exploring Ruby on Rails and PostgreSQLExploring Ruby on Rails and PostgreSQL
Exploring Ruby on Rails and PostgreSQL
 
JRuby Hot Topics 2008-12-12
JRuby Hot Topics 2008-12-12JRuby Hot Topics 2008-12-12
JRuby Hot Topics 2008-12-12
 
Yet Another Replication Tool: RubyRep
Yet Another Replication Tool: RubyRepYet Another Replication Tool: RubyRep
Yet Another Replication Tool: RubyRep
 
JRuby - The Best of Java and Ruby
JRuby - The Best of Java and RubyJRuby - The Best of Java and Ruby
JRuby - The Best of Java and Ruby
 
IJTC%202009%20JRuby
IJTC%202009%20JRubyIJTC%202009%20JRuby
IJTC%202009%20JRuby
 
IJTC%202009%20JRuby
IJTC%202009%20JRubyIJTC%202009%20JRuby
IJTC%202009%20JRuby
 
Rails performance at Justin.tv - Guillaume Luccisano
Rails performance at Justin.tv - Guillaume LuccisanoRails performance at Justin.tv - Guillaume Luccisano
Rails performance at Justin.tv - Guillaume Luccisano
 
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
 
Adventures of java developer in ruby world
Adventures of java developer in ruby worldAdventures of java developer in ruby world
Adventures of java developer in ruby world
 
Introduction to Go
Introduction to GoIntroduction to Go
Introduction to Go
 
Rubymotion trip to inspect 2013
Rubymotion trip to inspect 2013Rubymotion trip to inspect 2013
Rubymotion trip to inspect 2013
 
Seattlerb why jruby
Seattlerb why jrubySeattlerb why jruby
Seattlerb why jruby
 
Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0
 
The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018
 
The story of language development
The story of language developmentThe story of language development
The story of language development
 
node.js in action
node.js in actionnode.js in action
node.js in action
 
GitHub Notable OSS Project
GitHub  Notable OSS ProjectGitHub  Notable OSS Project
GitHub Notable OSS Project
 
The Future of library dependency management of Ruby
 The Future of library dependency management of Ruby The Future of library dependency management of Ruby
The Future of library dependency management of Ruby
 

Más de Charles 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
 
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
 
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
 
Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012Charles Nutter
 
Aloha RubyConf 2012 - JRuby
Aloha RubyConf 2012 - JRubyAloha RubyConf 2012 - JRuby
Aloha RubyConf 2012 - JRubyCharles Nutter
 
JavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesJavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesCharles Nutter
 
High Performance Ruby - Golden Gate RubyConf 2012
High Performance Ruby - Golden Gate RubyConf 2012High Performance Ruby - Golden Gate RubyConf 2012
High Performance Ruby - Golden Gate RubyConf 2012Charles Nutter
 
InvokeDynamic - You Ain't Seen Nothin Yet
InvokeDynamic - You Ain't Seen Nothin YetInvokeDynamic - You Ain't Seen Nothin Yet
InvokeDynamic - You Ain't Seen Nothin YetCharles Nutter
 
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...Charles Nutter
 
JavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesJavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesCharles Nutter
 

Más de Charles Nutter (20)

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
 
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
 
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
 
Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012
 
Aloha RubyConf 2012 - JRuby
Aloha RubyConf 2012 - JRubyAloha RubyConf 2012 - JRuby
Aloha RubyConf 2012 - JRuby
 
JavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesJavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for Dummies
 
High Performance Ruby - Golden Gate RubyConf 2012
High Performance Ruby - Golden Gate RubyConf 2012High Performance Ruby - Golden Gate RubyConf 2012
High Performance Ruby - Golden Gate RubyConf 2012
 
Euruko 2012 - JRuby
Euruko 2012 - JRubyEuruko 2012 - JRuby
Euruko 2012 - JRuby
 
InvokeDynamic - You Ain't Seen Nothin Yet
InvokeDynamic - You Ain't Seen Nothin YetInvokeDynamic - You Ain't Seen Nothin Yet
InvokeDynamic - You Ain't Seen Nothin Yet
 
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
 
JavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesJavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for Dummies
 

Último

UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1DianaGray10
 
Digital magic. A small project for controlling smart light bulbs.
Digital magic. A small project for controlling smart light bulbs.Digital magic. A small project for controlling smart light bulbs.
Digital magic. A small project for controlling smart light bulbs.francesco barbera
 
PicPay - GenAI Finance Assistant - ChatGPT for Customer Service
PicPay - GenAI Finance Assistant - ChatGPT for Customer ServicePicPay - GenAI Finance Assistant - ChatGPT for Customer Service
PicPay - GenAI Finance Assistant - ChatGPT for Customer ServiceRenan Moreira de Oliveira
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...Aggregage
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesMd Hossain Ali
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URLRuncy Oommen
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureEric D. Schabell
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding TeamAdam Moalla
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Commit University
 
Things you didn't know you can use in your Salesforce
Things you didn't know you can use in your SalesforceThings you didn't know you can use in your Salesforce
Things you didn't know you can use in your SalesforceMartin Humpolec
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfDaniel Santiago Silva Capera
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxMatsuo Lab
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsSeth Reyes
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6DianaGray10
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfDianaGray10
 
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationUsing IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationIES VE
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8DianaGray10
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 
Cybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxCybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxGDSC PJATK
 

Último (20)

UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
 
Digital magic. A small project for controlling smart light bulbs.
Digital magic. A small project for controlling smart light bulbs.Digital magic. A small project for controlling smart light bulbs.
Digital magic. A small project for controlling smart light bulbs.
 
PicPay - GenAI Finance Assistant - ChatGPT for Customer Service
PicPay - GenAI Finance Assistant - ChatGPT for Customer ServicePicPay - GenAI Finance Assistant - ChatGPT for Customer Service
PicPay - GenAI Finance Assistant - ChatGPT for Customer Service
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URL
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability Adventure
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)
 
Things you didn't know you can use in your Salesforce
Things you didn't know you can use in your SalesforceThings you didn't know you can use in your Salesforce
Things you didn't know you can use in your Salesforce
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptx
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and Hazards
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
 
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationUsing IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 
Cybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxCybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptx
 

High Performance Ruby - E4E Conference 2013

  • 1. High Performance Ruby Tips,Techniques, and Futures Monday, July 1, 13
  • 2. Me • Charles Oliver Nutter • @headius • Java developer since 1996 • JRuby developer since 2006 • Red Hat / JBoss polyglot group Monday, July 1, 13
  • 4. Is Ruby fast enough? Monday, July 1, 13
  • 5. How fast do you need Ruby to be? Monday, July 1, 13
  • 6. What Should We Optimize? • Overall execution time? • Memory use? • Developer time? • Developer happiness? :-) Monday, July 1, 13
  • 7. Ruby can be fast... if you know how. Monday, July 1, 13
  • 8. Strategies • Use a better runtime • Use more cores • Write better code Monday, July 1, 13
  • 10. Many Options • Ruby 2.0 • Significant execution improvements • JRuby • Leveraging JVM more and more • Rubinius • OptimizingVM built for Ruby Monday, July 1, 13
  • 11. 0 7.5 15 22.5 30 Java 1.4 Java 5 Java 6 Java 7 Go Java Go! JRuby 1.0.3 (bm_red_black_tree.rb) 300% for free Monday, July 1, 13
  • 12. 0 2 4 6 8 1.0.3 1.1.6 1.4.0 1.5.6 1.6.8 1.7.0 OpenJDK 8 (bm_red_black_tree.rb) Go JRuby Go! 8.2x Improvement Monday, July 1, 13
  • 13. rbtree Extension • Pure Ruby version works everywhere • C or Java extension FOR SPEED • Oh really? ;-) Monday, July 1, 13
  • 15. 0 1 2 3 4 ruby-1.9.3 + Ruby ruby-2.0.0 + Ruby maglev + Ruby macruby-0.12 + Ruby rbx-2.0.0rc1 + Ruby ruby-1.9.3 + C ext ruby-2.0.0 + C ext jruby + Ruby jruby + Java ext red/black tree, pure Ruby versus native Runtime per iteration Monday, July 1, 13
  • 16. 0 1 2 3 4 ruby-1.9.3 + Ruby ruby-2.0.0 + Ruby maglev + Ruby macruby-0.12 + Ruby rbx-2.0.0rc1 + Ruby ruby-1.9.3 + C ext ruby-2.0.0 + C ext jruby + Ruby jruby + Java ext 3.96 red/black tree, pure Ruby versus native Runtime per iteration Monday, July 1, 13
  • 17. 0 1 2 3 4 ruby-1.9.3 + Ruby ruby-2.0.0 + Ruby maglev + Ruby macruby-0.12 + Ruby rbx-2.0.0rc1 + Ruby ruby-1.9.3 + C ext ruby-2.0.0 + C ext jruby + Ruby jruby + Java ext 3.96 2.48 red/black tree, pure Ruby versus native Runtime per iteration Monday, July 1, 13
  • 18. 0 1 2 3 4 ruby-1.9.3 + Ruby ruby-2.0.0 + Ruby maglev + Ruby macruby-0.12 + Ruby rbx-2.0.0rc1 + Ruby ruby-1.9.3 + C ext ruby-2.0.0 + C ext jruby + Ruby jruby + Java ext 3.96 2.48 1.39 red/black tree, pure Ruby versus native Runtime per iteration Monday, July 1, 13
  • 19. 0 1 2 3 4 ruby-1.9.3 + Ruby ruby-2.0.0 + Ruby maglev + Ruby macruby-0.12 + Ruby rbx-2.0.0rc1 + Ruby ruby-1.9.3 + C ext ruby-2.0.0 + C ext jruby + Ruby jruby + Java ext 3.96 2.48 1.39 1.19 red/black tree, pure Ruby versus native Runtime per iteration Monday, July 1, 13
  • 20. 0 1 2 3 4 ruby-1.9.3 + Ruby ruby-2.0.0 + Ruby maglev + Ruby macruby-0.12 + Ruby rbx-2.0.0rc1 + Ruby ruby-1.9.3 + C ext ruby-2.0.0 + C ext jruby + Ruby jruby + Java ext 3.96 2.48 1.39 1.19 0.51 red/black tree, pure Ruby versus native Runtime per iteration Monday, July 1, 13
  • 21. 0 1 2 3 4 ruby-1.9.3 + Ruby ruby-2.0.0 + Ruby maglev + Ruby macruby-0.12 + Ruby rbx-2.0.0rc1 + Ruby ruby-1.9.3 + C ext ruby-2.0.0 + C ext jruby + Ruby jruby + Java ext 3.96 2.48 1.39 1.19 0.51 0.51 red/black tree, pure Ruby versus native Runtime per iteration Monday, July 1, 13
  • 22. 0 1 2 3 4 ruby-1.9.3 + Ruby ruby-2.0.0 + Ruby maglev + Ruby macruby-0.12 + Ruby rbx-2.0.0rc1 + Ruby ruby-1.9.3 + C ext ruby-2.0.0 + C ext jruby + Ruby jruby + Java ext 3.96 2.48 1.39 1.19 0.51 0.51 0.51 red/black tree, pure Ruby versus native Runtime per iteration Monday, July 1, 13
  • 23. 0 1 2 3 4 ruby-1.9.3 + Ruby ruby-2.0.0 + Ruby maglev + Ruby macruby-0.12 + Ruby rbx-2.0.0rc1 + Ruby ruby-1.9.3 + C ext ruby-2.0.0 + C ext jruby + Ruby jruby + Java ext 3.96 2.48 1.39 1.19 0.51 0.51 0.51 0.29 red/black tree, pure Ruby versus native Runtime per iteration Monday, July 1, 13
  • 24. 0 1 2 3 4 ruby-1.9.3 + Ruby ruby-2.0.0 + Ruby maglev + Ruby macruby-0.12 + Ruby rbx-2.0.0rc1 + Ruby ruby-1.9.3 + C ext ruby-2.0.0 + C ext jruby + Ruby jruby + Java ext 3.96 2.48 1.39 1.19 0.51 0.51 0.51 0.29 0.1 red/black tree, pure Ruby versus native Runtime per iteration Monday, July 1, 13
  • 26. Dynamic Optimization • Target method/value discovered at runtime • Lookup is expensive • We can cache it • Cache has to be validated • Indirection hurts pipeline • Inline methods/values at access point Monday, July 1, 13
  • 27. Method Caching Target Object FooClass def foo ... def bar ... associated with obj.foo() VM method table Monday, July 1, 13
  • 28. VM Operations Method Caching Target Object FooClass def foo ... def bar ... associated with obj.foo() VM Call Site method table Monday, July 1, 13
  • 29. VM Operations Method Lookup Method Caching Target Object FooClass def foo ... def bar ... associated with obj.foo() VM Call Site method table Monday, July 1, 13
  • 30. VM Operations Method Lookup Method Caching Target Object FooClass def foo ... def bar ... associated with obj.foo() VM def foo ... Call Site method table Monday, July 1, 13
  • 31. VM Operations Method Lookup Branch Method Caching Target Object FooClass def foo ... def bar ... associated with obj.foo() VM def foo ... Call Site method table Monday, July 1, 13
  • 32. VM Operations Method Lookup Branch Method Cache Method Caching Target Object FooClass def foo ... def bar ... associated with obj.foo() VM def foo ... Call Site method table Monday, July 1, 13
  • 34. VM Operations Constant Lookup Constant Table MY_CONST VM Access Site Monday, July 1, 13
  • 35. VM Operations LocateValue Constant Lookup Constant Table MY_CONST VM Access Site value Monday, July 1, 13
  • 36. VM Operations LocateValue Bind Permanently Constant Lookup Constant Table MY_CONST VM Access Site value Monday, July 1, 13
  • 37. def foo; 1; end def invoker; foo; end i = 0 while i < 10000   invoker   i+=1 end Inlining Monday, July 1, 13
  • 38. def invoker; 1; end i = 0 while i < 10000   invoker   i+=1 end Inline foo into invoker Monday, July 1, 13
  • 39. i = 0 while i < 10000   1   i+=1 end Inline invoker into loop Monday, July 1, 13
  • 40. i = 0 while i < 10000   i+=1 end Value is transient Monday, July 1, 13
  • 41. i = 10000 Loop does nothing Monday, July 1, 13
  • 42. Variable i is never read Monday, July 1, 13
  • 44. It's a multi-core world • Scaling today is horizontal, not vertical • N processes does not cut it • N users * X MB process = $$$ • CoW is only a partial band-aid • Non-parallel impls are falling behind • JRuby, Rubinius your only real options Monday, July 1, 13
  • 46. True Parallellism Ruby Threads Native Threads Ruby 1.8.7 Green Threading CPU Cores in Use Single Thread Monday, July 1, 13
  • 47. True Parallellism Ruby Threads Native Threads Ruby 1.8.7 Ruby 2.0.0 Green Threading CPU Cores in Use Global LockSingle Thread Monday, July 1, 13
  • 48. True Parallellism Ruby Threads Native Threads Ruby 1.8.7 Ruby 2.0.0 Green Threading CPU Cores in Use JRuby Global LockSingle Thread Real Threading Monday, July 1, 13
  • 49. Multicore in MRI 200MB MRI Instance 200MB MRI Instance 200MB MRI Instance 200MB MRI Instance 200MB MRI Instance 200MB MRI Instance 200MB MRI Instance 200MB MRI Instance 200MB MRI Instance 200MB MRI Instance 200MB MRI Instance Ten instances * 200MB = 2GB Monday, July 1, 13
  • 50. Multicore in JRuby 300MB JRuby Instance One instance across 10 threads = 300MB Monday, July 1, 13
  • 51. require 'benchmark' ary = (1..1000000).to_a loop {   puts Benchmark.measure {     10.times {       ary.each {|i|}     }   } } Monday, July 1, 13
  • 52. require 'benchmark' ary = (1..1000000).to_a loop {   puts Benchmark.measure {     (1..10).map {       Thread.new {         ary.each {|i|}       }     }.map(&:join)   } } Monday, July 1, 13
  • 54. Ruby 1.9 single thread JRuby single thread Monday, July 1, 13
  • 55. Ruby 1.9 single thread Ruby 1.9 multiple threads JRuby single thread JRuby multiple threads Monday, July 1, 13
  • 56. 0.2s 0.35s 0.5s 0.65s 0.8s one thread two threads three threads four threads Per-iteration time versus thread count threaded_reverse Monday, July 1, 13
  • 57. Doing It Right • Lock-free persistent data structures • hamster et al • Thread-safety utilities • Mutex, Queue, thread_safe + atomic gems • Threaded servers • puma, trinidad, torquebox, JVM servers Monday, July 1, 13
  • 58. Finding Problems • JRuby • VM flags (heap/thread dumps, debug) • Some of the best tools in the world • Rubinius • gdb, OS-level tools • #rubinius Monday, July 1, 13
  • 60. • eval • Exceptions as flow control • Excessive allocation • Defeating optimizations • IO, DB, bad libraries • VM flaw* Usual Suspects *I usually assume it's JRuby's fault until proven otherwise Monday, July 1, 13
  • 61. eval • Code never stays the same • VM can't cache, can't see patterns • No optimization is possible* *Specific cases can sometimes be cached and optimized Monday, July 1, 13
  • 62. Fixing eval • Evaluate code into a method and leave it • Methods are stable, optimizable • Pass dynamic state, rather than interpolate • Branches are cheaper than new code • Do all evaluation up front • ...not during your app's hot path Monday, July 1, 13
  • 63. Exceptions • Act like a special return value • Construct object with information • Capture call stack at raise point • Unroll call stack until rescued • Overhead ranges from big to huge • Especially costly on optimizingVMs Monday, July 1, 13
  • 64. def foo(a); raise; rescue; return a + 1; end Shallow stack, 100k calls: JRuby w/ exception: 7.7s JRuby w/o exception: 0.004s Ruby 2 w/ exception: 0.25s Ruby 2 w/o exception: 0.009s Rubinius w/ exception: 0.1s Rubinius w/o exception: 0.002s Monday, July 1, 13
  • 65. def foo(a); raise; rescue; return a + 1; end Deep stack, 100k calls: JRuby w/ exception: 200s Ruby 2 w/ exception: 1.25s Rubinius w/ exception: 7.7s Monday, July 1, 13
  • 66. Exception Alternatives • Pre-allocated exception object • Empty backtrace passed to raise() • Special return value • Check at each caller • catch/throw • Avoids most overhead Monday, July 1, 13
  • 67. Allocation • Literals • "foo" creates object every time • String + String,Array + Array • Creates intermediate objects • += is especially wasteful • Slicing and enumerating • ary.map{}.select{}.inject{}.find = 3 arrays Monday, July 1, 13
  • 68. Fixing Literals • Constants are your friends • Optimizes well on most impls • Avoids literal churn • Cache common interpolated values • Study memory profiles Monday, July 1, 13
  • 69. Fixing Concat/Copy • Modify in place • Thread-safety trade-offs... • Use persistent structures • "hamster" gem • Google "immutable ruby" Monday, July 1, 13
  • 70. Fixing Enum Chaining • Condense into fewer steps • Lazy Enumerator in 2.0 • Just use a loop :-) Monday, July 1, 13
  • 71. Defeating Optimization • Caching and inlining are key to perf • If we can't cache... • Methods won't inline, won't optimize • Constants must be looked up every time • We have less time for real work Monday, July 1, 13
  • 72. Method Cache Busting • VM must ensure cache is correct • Check type • Ensure method table is the same • New type every time? No caching. • Modify method table? No caching. Monday, July 1, 13
  • 73. VM Operations Method Lookup Branch Method Cache Dynamic Invocation Target Object FooClass def foo ... def bar ... associated with obj.foo() VM Call Site method table Monday, July 1, 13
  • 74. VM Operations Method Lookup Branch Method Cache Dynamic Invocation Target Object FooClass def foo ... def bar ... associated with obj.foo() VM def foo ... Call Site method table Monday, July 1, 13
  • 75. VM Operations Method Lookup Branch Method Cache Dynamic Invocation Target Object FooClass def foo ... def bar ... associated with obj.foo() VM Call Site method table Monday, July 1, 13
  • 76. VM Operations Method Lookup Branch Method Cache Dynamic Invocation Target Object FooClass def foo ... def bar ... associated with obj.foo() VM def foo ... Call Site method table Monday, July 1, 13
  • 77. VM Operations Method Lookup Branch Method Cache Dynamic Invocation Target Object FooClass def foo ... def bar ... associated with obj.foo() VM Call Site method table Monday, July 1, 13
  • 78. VM Operations Method Lookup Branch Method Cache Dynamic Invocation Target Object FooClass def foo ... def bar ... associated with obj.foo() VM def foo ... Call Site method table Monday, July 1, 13
  • 79. VM Operations Method Lookup Branch Method Cache Dynamic Invocation Target Object FooClass def foo ... def bar ... associated with obj.foo() VM Call Site method table Monday, July 1, 13
  • 80. VM Operations Method Lookup Branch Method Cache Dynamic Invocation Target Object FooClass def foo ... def bar ... associated with obj.foo() VM def foo ... Call Site method table Monday, July 1, 13
  • 81. VM Operations Method Lookup Branch Method Cache Dynamic Invocation Target Object FooClass def foo ... def bar ... associated with obj.foo() VM Call Site method table Monday, July 1, 13
  • 82. VM Operations Method Lookup Branch Method Cache Dynamic Invocation Target Object FooClass def foo ... def bar ... associated with obj.foo() VM def foo ... Call Site method table Monday, July 1, 13
  • 83. Singletons • Creates new types at runtime • Impossible to cache based on type • Usually defines new methods • Method table is always different class << foo ... def foo.bar ... Monday, July 1, 13
  • 84. Object#extend • Includes module into single object • New one-off type every time • Class hierarchy keeps changing foo.extend Enumerable Monday, July 1, 13
  • 85. static VALUE io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock) { ... n = rb_read_internal(fptr->fd, RSTRING_PTR(str), len); rb_str_unlocktmp(str); if (n < 0) { if (!nonblock && rb_io_wait_readable(fptr->fd)) goto again; if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) rb_mod_sys_fail(rb_mWaitReadable, "read would block"); rb_sys_fail_path(fptr->pathv); } ... } Monday, July 1, 13
  • 86. static VALUE io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock) { ... n = rb_read_internal(fptr->fd, RSTRING_PTR(str), len); rb_str_unlocktmp(str); if (n < 0) { if (!nonblock && rb_io_wait_readable(fptr->fd)) goto again; if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) rb_mod_sys_fail(rb_mWaitReadable, "read would block"); rb_sys_fail_path(fptr->pathv); } ... } Monday, July 1, 13
  • 87. void rb_mod_sys_fail(VALUE mod, const char *mesg) { VALUE exc = make_errno_exc(mesg); rb_extend_object(exc, mod); rb_exc_raise(exc); } Monday, July 1, 13
  • 88. void rb_mod_sys_fail(VALUE mod, const char *mesg) { VALUE exc = make_errno_exc(mesg); rb_extend_object(exc, mod); rb_exc_raise(exc); } Monday, July 1, 13
  • 89. Fixing Singletons/ #extend • Functional patterns • FooLibrary.process(obj) rather than obj.extend FooLibrary; obj.process • Create types up front (programmatically?) • 1000 predefined types beats infinite types Monday, July 1, 13
  • 92. Constant Lookup • Constants in tables on classes/modules • Usually assigned only once, at load time • Lookup is expensive, like methods • Values can be cached Monday, July 1, 13
  • 93. Constant Cache • Constant search proceeds two ways • First, lexical scoping • Second, class hierarchy • Invalidation happens globally Monday, July 1, 13
  • 94. Constant Cache Busting • Redefining constants • Introducing new lexical scopes • Classes created at runtime • Evaluated code • Altering class hierarchies • Lookup results may change...no caching Monday, July 1, 13
  • 95. Fixing Constants • Don't modify them • i.e. CONSTANT • Avoid runtime class hierarchy changes Monday, July 1, 13
  • 96. How to Get Help Monday, July 1, 13
  • 97. Performance Issues • Assume nothing...most can be fixed • Isolate bad code, small a case as possible • UseVM tools to monitor caches • Fix if it's your bug, PR if it's a library • Come to us for help or if it's aVM bug • Repeat... Monday, July 1, 13
  • 98. Concurrency Issues • Avoid mutable state • Synchronize mutations • Start coarse-grained, get finer over time • VM tooling to monitor locks, contention • ContactVM authors for help Monday, July 1, 13
  • 100. Ruby can be fast...and we want to help you. Monday, July 1, 13
  • 101. ThankYou! • Charles Oliver Nutter • @headius • http://jruby.org • http://blog.headius.com • Book: "Using JRuby" • Book: "Deploying JRuby" Monday, July 1, 13