SlideShare une entreprise Scribd logo
1  sur  100
Télécharger pour lire hors ligne
The FUTURE of
Tuesday, September 17, 13
Me
• Charles Oliver Nutter
• @headius
• Java developer since 1996
• JRuby developer since 2006
• Red Hat / JBoss polyglot group
Tuesday, September 17, 13
Have you heard of
JRuby?
Tuesday, September 17, 13
Have you tried
JRuby?
Tuesday, September 17, 13
Are you using
JRuby?
Tuesday, September 17, 13
What is JRuby?
Tuesday, September 17, 13
Ruby on the JVM
Tuesday, September 17, 13
Ruby on the JVM
I don't like Java so I don'tlike JRuby
Tuesday, September 17, 13
Ruby on the JVM
I don't like Java so I don'tlike JRuby
LOL applets
Tuesday, September 17, 13
Ruby on the JVM
JVM SUCKS ROFL
I don't like Java so I don'tlike JRuby
LOL applets
Tuesday, September 17, 13
Ruby on the JVM
JVM SUCKS ROFL
AbstractMetaRubyImplementationFactoryFactoryImpl
I don't like Java so I don'tlike JRuby
LOL applets
Tuesday, September 17, 13
Welcome to Spain
Tuesday, September 17, 13
Welcome to Spain
Tuesday, September 17, 13
Welcome to Spain
Tuesday, September 17, 13
Welcome to Spain
Tuesday, September 17, 13
Welcome to Spain
Tuesday, September 17, 13
Welcome to Spain
Tuesday, September 17, 13
Welcome to Spain
Tuesday, September 17, 13
JRuby is Ruby!!!
on the JVM... shhh!
Tuesday, September 17, 13
The Basics
• Compatible with Ruby 1.8.7, 1.9.3
• Mostly written in (clean) Java
• More and more in Ruby going forward
• Entire world of JVM libraries available
JVM
JDK Classes Other Libraries
JRuby Core Classes JRuby Runtime
More Core Classes Standard Lib Extras
Your Application
FFI
Tuesday, September 17, 13
Roadmap
1.6.0
1.6.1
1.6.2 1.6.3 1.6.7.2
1.7.0.pre1
1.6.4
...
1.6.8
...
1.7.3 1.7.4 1.7.5
1.7.6
...
9000!
Next week or two
Tuesday, September 17, 13
JRuby 9000 really is the
next version...
9k
...Coming 2014
Tuesday, September 17, 13
One point release
later...
Tuesday, September 17, 13
9K Questions
• Ruby 2.0 or 2.1-only?
• 1.8 support gone
• 1.9 support gone
• Java 7+ only?
• New compiler will be... ?
Tuesday, September 17, 13
Why JRuby?
Tuesday, September 17, 13
JRuby Team
Tuesday, September 17, 13
JRuby Team
Charlie
Tuesday, September 17, 13
JRuby Team
Charlie Tom
Nick Hiro Marcin Nahi Wayne Subbu DouglasDouglasContribsDouglas
Tuesday, September 17, 13
JRuby Team
Charlie Tom
Nick Hiro Marcin Nahi Wayne Subbu DouglasDouglasContribs
DouglasDouglasOpenJDK
DouglasDouglasAndroid
DouglasDouglasJ9
DouglasDouglasOther
JVMs
Douglas
Tuesday, September 17, 13
JVM Over Time
0
7.5
15
22.5
30
Java 1.4 Java 5 Java 6 Java 7
JRuby 1.0.3 (bm_red_black_tree.rb)
Tuesday, September 17, 13
Versus MRI 1.8
0
7.5
15
22.5
30
Java 1.4 Java 5 Java 6 Java 7
JRuby 1.0.3 (bm_red_black_tree.rb) MRI 1.8
Tuesday, September 17, 13
0ms
75ms
150ms
225ms
300ms
188KB/29MB 27MB/127MB 199MB/238MB
Time per GC versus heap usage
TimeperGC
Heap usage (MRI/JRuby)
Ruby 2.0.0 JRuby
Tuesday, September 17, 13
Features Over Time
1.6 1.8.4 1.8.6 1.8.7 1.9.2 1.9.3 2.0 2.1
Ruby Features
JRuby Support
Tuesday, September 17, 13
However...
• JVM development is not fast
• JRuby must move forward
• Constantly improving
Tuesday, September 17, 13
What could be better?
Performance
Native Extensions
Concurrency
Startup Time
Tuesday, September 17, 13
Performance
Tuesday, September 17, 13
Hard to Optimize
• Dynamic calls with lots of overhead
• Dynamic object structure with indirection
• Lots and lots of objects
Tuesday, September 17, 13
Solutions
Tuesday, September 17, 13
Compile to Bytecode
• JVM likes JVM bytecode (surprise!)
• Simple compilation of Ruby
• Let JVM do the work
• Can we do better?
Tuesday, September 17, 13
Invokedynamic
• New JVM feature for languages
• Bytecode + IR to describe calls
• JVM patches straight through
• Optimize any kind of call like Java
• Ruby as fast as Java...in theory
Tuesday, September 17, 13
Tuesday, September 17, 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
Tuesday, September 17, 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.96s
2.48s
red/black tree, pure Ruby versus native
Runtime per iteration
Tuesday, September 17, 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.96s
2.48s
1.39s
1.19s
red/black tree, pure Ruby versus native
Runtime per iteration
Tuesday, September 17, 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.96s
2.48s
1.39s
1.19s
0.51s
0.51s
0.51s
red/black tree, pure Ruby versus native
Runtime per iteration
Tuesday, September 17, 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.96s
2.48s
1.39s
1.19s
0.51s
0.51s
0.51s
0.29s
0.1s
red/black tree, pure Ruby versus native
Runtime per iteration
Tuesday, September 17, 13
But...
• Indy was really slow in first Java 7 release
• Got fast in 7u2...and turned out broken
• Rewritten for 7u40
• Slow to warm up
• Getting reports that there's still issues
• Java 8 due in March
Tuesday, September 17, 13
Other Options
• New IR compiler/runtime in 9k
• Optimize Ruby code before JVM
• Specialize types, elide allocations
Tuesday, September 17, 13
Lexical
Analysis
Parsing
Semantic
Analysis
Optimization
Bytecode
Generation
Interpret
AST
IR Instructions
CFG DFG ...
Existing
New!
Dalvik
Generation
...
Tuesday, September 17, 13
1 check_arity(2, 0, -1)
2 a(0:0) = recv_pre_reqd_arg(0)
3 thread_poll
4 line_num(2)
5 %v_2 = call(+, a(0:0), [1:Fixnum])
6 return(%v_2)
-Xir.passes=LocalOptimizationPass,DeadCodeElimination
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a(0:0) = recv_pre_reqd_arg(0)
2 b(0:1) = recv_pre_reqd_arg(1)
3 %block(0:2) = recv_closure
4 thread_poll
5 line_num(1)
6 c(0:3) = 1:fixnum
7 line_num(2)
8 %v_0 = call(+, a(0:0), [c(0:3)])
9 d(0:4) = copy(%v_0)
10 return(%v_0)
Optimization
propagation
Tuesday, September 17, 13
Other Options
• Truffle/Graal
• New compiler backends from Oracle
• Graal = direct API to native JIT
• Truffle = magic optimizing AST atop Graal
• Ruby on Truffle 5x-6x faster than JRuby
• But...
Tuesday, September 17, 13
The Hard Part
{
Tuesday, September 17, 13
Sooo....
• Keep working with JVM guys on InDy
• Get our own optimizing compiler done
• Explore Graal/Truffle backend
• Compiler geeks wanted! :-)
Tuesday, September 17, 13
Concurrency
Tuesday, September 17, 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
Tuesday, September 17, 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-way concurrency * 200MB = 2GB
Tuesday, September 17, 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
100-way concurrency * 200MB = 20GB
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
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
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
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
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
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
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
Tuesday, September 17, 13
Multicore in JRuby
300MB JRuby
Instance
One instance across 10 threads = 300MB
Tuesday, September 17, 13
Multicore in JRuby
300MB JRuby
Instance
One instance across 100 threads = 300MB
Tuesday, September 17, 13
But...
• Ruby world is still growing up
• Concurrency tools being created
• Libraries being made threadsafe
• We need to do more to help
Tuesday, September 17, 13
Unsafe Operations
• Concurrent read+write on core structures
• Non-atomic updates
•@count +=1
•@cache ||= MyCache.new
• Thread pooling
• Coordinating threads
Tuesday, September 17, 13
thread_safe
• Concurrency-safe Hash
• Concurrency-safe Array
require 'thread_safe'
sa = ThreadSafe::Array.new
sh = ThreadSafe::Hash.new
Tuesday, September 17, 13
hamster
• Persistent collections for Ruby
• A la Clojure and others
simon = Hamster.hash(:name => "Simon", :gender => :male)
 
simon[:name] # => "Simon"
simon.get(:gender) # => :male
 
james = simon.put(:name, "James") # => {:name => "James", :gender => :male}
simon # => {:name => "Simon", :gender => :male}
james[:name] # => "James"
simon[:name] # => "Simon"
 
male = simon.delete(:name) # => {:gender => :male}
simon # => {:name => "Simon", :gender => :male}
male.has_key?(:name) # => false
simon.has_key?(:name) # => true
Tuesday, September 17, 13
atomic
• Atomic value holder
• Safely update current value
• Edit value only if unchanged
• Full CPU-level atomicity guarantees
Tuesday, September 17, 13
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
my_atomic = Atomic.new(0)
my_atomic.update {|v| v + 1}
begin
my_atomic.try_update {|v| v + 1}
rescue Atomic::ConcurrentUpdateError => cue
# deal with it (retry, propagate, etc)
end
Tuesday, September 17, 13
jo
• Threaded implementation of "goroutines"
• "channel" for communication
Tuesday, September 17, 13
# pinger ponger printer
def pinger(c)
20.times { c << 'ping' }
end
def ponger(c)
20.times { c << 'pong' }
end
def printer(c)
40.times do
puts c.take
sleep 1
end
end
c = chan
jo {pinger(c)} # all on separate threads
jo {ponger(c)}
jo {printer(c)}
Tuesday, September 17, 13
Bottom Line
• Concurrency can work in Ruby
• Use the right tools and patterns
• Immutability FTW
• Test your apps and libs on JRuby!
Tuesday, September 17, 13
Native Extensions
Tuesday, September 17, 13
Why Not Ruby?
• Performance
• Fine grained (lots of calls down to C)
• Coarse grained (toss work over the wall)
• Library access
Tuesday, September 17, 13
JRuby 1.6 C Exts
• Limited support (now disabled)
• Will be moved to external gem
• If you want it, support it
• Some stuff worked...most didn’t
Tuesday, September 17, 13
Problems
• Performance
• Data copying to emulate raw structs
• Locking to keep C code thread-safe
• Multiple JRuby instances in one JVM
• No way from C to know which one
• Huge API to support
Tuesday, September 17, 13
Alternatives
Tuesday, September 17, 13
Java Integration
• Call Java (Scala, Clojure, ...) from Ruby
• Smart mapping of method names
• Type conversions as appropriate
• Super easy and fun
Tuesday, September 17, 13
import javax.swing.JFrame
import javax.swing.JLable
frame = JFrame.new("Window")
label = JLabel.new("Hello")
frame.add(label)
frame.default_close_operation = JFrame::EXIT_ON_CLOSE
frame.pack
frame.visible = true
Tuesday, September 17, 13
Java Native Extensions
• Similar to C ext for MRI, but with Java
• Fast call protocol...basically free
• Same GC for all objects
• Have to keep in sync if C version too
Tuesday, September 17, 13
FFI
• Ruby API/DSL for calling native code
• Runs on all Ruby impls
• Maintained by JRuby team!
• Solves "access" use case
• Works well for coarse-grained calls
Tuesday, September 17, 13
Ruby FFI example
class Timeval < FFI::Struct
  layout :tv_sec => :ulong,
:tv_usec => :ulong
end
module LibC
  extend FFI::Library
  ffi_lib FFI::Library::LIBC
  attach_function :gettimeofday,
[ :pointer, :pointer ],
:int
end
t = Timeval.new
LibC.gettimeofday(t.pointer, nil)
Tuesday, September 17, 13
But...
• Struct binding issues
• Across OSes (also 32+64 bit archs)
• Across library versions
• Library compile option mismatches
• Fine-grained perf sometimes suffers
Tuesday, September 17, 13
Ruby FFI Generator
• https://github.com/neelance/ffi-gen
• Clang-based Ruby FFI generator
• Used to generate clang binding it uses
• It's meta!
Tuesday, September 17, 13
require "ffi/gen"
FFI::Gen.generate(
module_name: "Clang",
ffi_lib: "clang",
headers: ["clang-c/Index.h"],
cflags: `llvm-config --cflags`.split(" "),
prefixes: ["clang_", "CX"],
output: "clang-c/index.rb"
)
Tuesday, September 17, 13
  # A single translation unit, which resides in an index.
  class TranslationUnitImpl < FFI::Struct
    layout :dummy, :char
  end
  # Identifies a specific source location within a translation
  # unit.
  #
  # Use clang_getExpansionLocation() or clang_getSpellingLocation()
  # to map a source location to a particular file, line, and column.
  #
  # = Fields:
  # :ptr_data ::
  # (Array<FFI::Pointer(*Void)>)
  # :int_data ::
  # (Integer)
  class SourceLocation < FFI::Struct
    layout :ptr_data, [:pointer, 2],
           :int_data, :uint
  end
Tuesday, September 17, 13
  # Retrieves the source location associated with a given file/line/column
  # in a particular translation unit.
  #
  # @method get_location(tu, file, line, column)
  # @param [TranslationUnitImpl] tu
  # @param [FFI::Pointer(File)] file
  # @param [Integer] line
  # @param [Integer] column
  # @return [SourceLocation]
  # @scope class
  attach_function :get_location, :clang_getLocation,
[TranslationUnitImpl, :pointer, :uint, :uint],
SourceLocation.by_value
Tuesday, September 17, 13
XNI
• Ruby + plain old C
• Covers access and perf cases
• Cross-implementation support
• Struct mapping in compile phase
• Experimental
https://github.com/wmeissner/xni
Tuesday, September 17, 13
hitimes C Ext
/**
* call-seq:
* interval.start -> boolean
*
* mark the start of the interval. Calling start on an already started
* interval has no effect. An interval can only be started once. If the
* interval is truely started +true+ is returned otherwise +false+.
*/
VALUE hitimes_interval_start( VALUE self )
{
    hitimes_interval_t *i;
    VALUE rc = Qfalse;
    Data_Get_Struct( self, hitimes_interval_t, i );
    if ( 0L == i->start_instant ) {
      i->start_instant = hitimes_get_current_instant( );
      i->stop_instant = 0L;
      i->duration = -1.0l;
      rc = Qtrue;
    }
    return rc;
}
Tuesday, September 17, 13
hitimes XNI
/**
* call-seq:
* interval.start -> boolean
*
* mark the start of the interval. Calling start on an already started
* interval has no effect. An interval can only be started once. If the
* interval is truely started +true+ is returned otherwise +false+.
*/
bool hitimes_interval_start( RubyEnv* env, hitimes_interval_t* i )
{
    if ( 0L == i->start_instant ) {
      i->start_instant = hitimes_get_current_instant( );
      i->stop_instant = 0L;
      i->duration = -1.0l;
      return true;
    }
    return false;
}
Tuesday, September 17, 13
Startup Time
Tuesday, September 17, 13
#1 Pain Point
Tuesday, September 17, 13
Hard Problem
• MRI boot time is 95% native
• JRuby boot time is 0% native code
• Mostly Java, which needs to warm up
• Parser, interpreter, core classes, compiler
• Even if our code is better, we start slow
Tuesday, September 17, 13
Child Processes
• Reduce need for sub-Ruby invokes
• rails -> clean rails env in child
• rails/rake -> bundler relaunch
• rake test -> 4+ processes in Rails
• rake -> rspec in subprocess
• Fix requires changing many libraries
Tuesday, September 17, 13
Lexical
Analysis
Parsing
Semantic
Analysis
Optimization
Bytecode
Generation
Interpret
AST
IR Instructions
CFG DFG ...
Existing
MORE
Dalvik
Generation
...
Tuesday, September 17, 13
Solutions
Tuesday, September 17, 13
Nailgun/Drip
• Always running background JVM
• Not quite production quality
• signals, IO
• Small Ruby scripts very fast
• Rails not much faster
• Lots of requires, objects, boot logic
Tuesday, September 17, 13
GSoC 2012
IR Persistence
IR Instructions
CFG DFG ...
file.ir
file.rb
compile
file.c
compile
file.o
Tuesday, September 17, 13
Reflection on GSoC
• Size matters
• # of bytes
• Intern()‘ing of identifiers matter
• Laziness can help a lot
Tuesday, September 17, 13
Defined vs Used Methods
CMD DEFINED USED SAVINGS
-e ‘:foo’ 501 33 ~93%
gem install
rails
1897 529 ~72%
rails scaffold 9411 1647 ~82%
rake
db:migrate
9397 1662 ~82%
rake spec 4595 904 ~80%
Tuesday, September 17, 13
New IR Persistence
• Binary format
• Constant pool to intern only once per id
• (currently once per occurrence)
• Incremental loading of method bodies
Tuesday, September 17, 13
Ultimate Startup!
rails new foo
JRuby Instance
IR Data
rails generate
JRuby Instance
rake db:migrate
JRuby Instance
Compile
Use
Use
Background
JVM
Tuesday, September 17, 13
Ruby is Strong
• Still growing and improving
• MRI too!
• Concurrency can be done
• C extensions are holding us back
• Never surrender!
Tuesday, September 17, 13
ThankYou!
• Charles Oliver Nutter
• @headius
• headius@headius.com
• http://blog.headius.com
Tuesday, September 17, 13

Contenu connexe

Similaire à The Future of JRuby - Baruco 2013

JRuby: What's Different (RORO Melbourne October 2011)
JRuby: What's Different (RORO Melbourne October 2011)JRuby: What's Different (RORO Melbourne October 2011)
JRuby: What's Different (RORO Melbourne October 2011)Charles 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
 
JRuby @ Boulder Ruby
JRuby @ Boulder RubyJRuby @ Boulder Ruby
JRuby @ Boulder RubyNick Sieger
 
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
 
Ruby Throwdown Hosted by Engine Yard
Ruby Throwdown Hosted by Engine YardRuby Throwdown Hosted by Engine Yard
Ruby Throwdown Hosted by Engine YardJacob Lehrbaum
 
Практики применения JRuby
Практики применения JRubyПрактики применения JRuby
Практики применения JRuby.toster
 
Rocket Fuelled Cucumbers
Rocket Fuelled CucumbersRocket Fuelled Cucumbers
Rocket Fuelled CucumbersJoseph Wilk
 
Ruby On Google App Engine 2nd Athens Ruby Me
Ruby On Google App Engine 2nd Athens Ruby MeRuby On Google App Engine 2nd Athens Ruby Me
Ruby On Google App Engine 2nd Athens Ruby MePanagiotis Papadopoulos
 
Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012Charles 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
 
Introduction to JRuby
Introduction to JRubyIntroduction to JRuby
Introduction to JRubyajuckel
 
Optcarrot: A Pure-Ruby NES Emulator
Optcarrot: A Pure-Ruby NES EmulatorOptcarrot: A Pure-Ruby NES Emulator
Optcarrot: A Pure-Ruby NES Emulatormametter
 
XRuby_Overview_20070831
XRuby_Overview_20070831XRuby_Overview_20070831
XRuby_Overview_20070831dreamhead
 
Concurrecy in Ruby
Concurrecy in RubyConcurrecy in Ruby
Concurrecy in RubyVesna Doknic
 
Ruby for C#-ers (ScanDevConf 2010)
Ruby for C#-ers (ScanDevConf 2010)Ruby for C#-ers (ScanDevConf 2010)
Ruby for C#-ers (ScanDevConf 2010)Thomas Lundström
 
Parallel Ruby: Managing the Memory Monster
Parallel Ruby: Managing the Memory MonsterParallel Ruby: Managing the Memory Monster
Parallel Ruby: Managing the Memory MonsterKevin Miller
 
Palestra no Grupo Sou Java
Palestra no Grupo Sou JavaPalestra no Grupo Sou Java
Palestra no Grupo Sou JavaFabio Akita
 
Rubinius 1.0 and more!
Rubinius 1.0 and more!Rubinius 1.0 and more!
Rubinius 1.0 and more!evanphx
 
JRuby Jam Session
JRuby Jam Session JRuby Jam Session
JRuby Jam Session Engine Yard
 

Similaire à The Future of JRuby - Baruco 2013 (20)

JRuby: What's Different (RORO Melbourne October 2011)
JRuby: What's Different (RORO Melbourne October 2011)JRuby: What's Different (RORO Melbourne October 2011)
JRuby: What's Different (RORO Melbourne October 2011)
 
High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013
 
JRuby @ Boulder Ruby
JRuby @ Boulder RubyJRuby @ Boulder Ruby
JRuby @ Boulder Ruby
 
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
 
Ruby Throwdown Hosted by Engine Yard
Ruby Throwdown Hosted by Engine YardRuby Throwdown Hosted by Engine Yard
Ruby Throwdown Hosted by Engine Yard
 
Практики применения JRuby
Практики применения JRubyПрактики применения JRuby
Практики применения JRuby
 
Rocket Fuelled Cucumbers
Rocket Fuelled CucumbersRocket Fuelled Cucumbers
Rocket Fuelled Cucumbers
 
Ruby On Google App Engine 2nd Athens Ruby Me
Ruby On Google App Engine 2nd Athens Ruby MeRuby On Google App Engine 2nd Athens Ruby Me
Ruby On Google App Engine 2nd Athens Ruby Me
 
Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012
 
The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018
 
Introduction to JRuby
Introduction to JRubyIntroduction to JRuby
Introduction to JRuby
 
Euruko 2012 - JRuby
Euruko 2012 - JRubyEuruko 2012 - JRuby
Euruko 2012 - JRuby
 
Optcarrot: A Pure-Ruby NES Emulator
Optcarrot: A Pure-Ruby NES EmulatorOptcarrot: A Pure-Ruby NES Emulator
Optcarrot: A Pure-Ruby NES Emulator
 
XRuby_Overview_20070831
XRuby_Overview_20070831XRuby_Overview_20070831
XRuby_Overview_20070831
 
Concurrecy in Ruby
Concurrecy in RubyConcurrecy in Ruby
Concurrecy in Ruby
 
Ruby for C#-ers (ScanDevConf 2010)
Ruby for C#-ers (ScanDevConf 2010)Ruby for C#-ers (ScanDevConf 2010)
Ruby for C#-ers (ScanDevConf 2010)
 
Parallel Ruby: Managing the Memory Monster
Parallel Ruby: Managing the Memory MonsterParallel Ruby: Managing the Memory Monster
Parallel Ruby: Managing the Memory Monster
 
Palestra no Grupo Sou Java
Palestra no Grupo Sou JavaPalestra no Grupo Sou Java
Palestra no Grupo Sou Java
 
Rubinius 1.0 and more!
Rubinius 1.0 and more!Rubinius 1.0 and more!
Rubinius 1.0 and more!
 
JRuby Jam Session
JRuby Jam Session JRuby Jam Session
JRuby Jam Session
 

Plus 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
 
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
 
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
 
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
 
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
 
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
 
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
 

Plus 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
 
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
 
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
 
JRuby: The Hard Parts
JRuby: The Hard PartsJRuby: The Hard Parts
JRuby: The Hard Parts
 
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
 
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
 
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
 
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
 

Dernier

Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Angeliki Cooney
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityWSO2
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
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
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 

Dernier (20)

Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
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
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 

The Future of JRuby - Baruco 2013

  • 1. The FUTURE of Tuesday, September 17, 13
  • 2. Me • Charles Oliver Nutter • @headius • Java developer since 1996 • JRuby developer since 2006 • Red Hat / JBoss polyglot group Tuesday, September 17, 13
  • 3. Have you heard of JRuby? Tuesday, September 17, 13
  • 5. Are you using JRuby? Tuesday, September 17, 13
  • 6. What is JRuby? Tuesday, September 17, 13
  • 7. Ruby on the JVM Tuesday, September 17, 13
  • 8. Ruby on the JVM I don't like Java so I don'tlike JRuby Tuesday, September 17, 13
  • 9. Ruby on the JVM I don't like Java so I don'tlike JRuby LOL applets Tuesday, September 17, 13
  • 10. Ruby on the JVM JVM SUCKS ROFL I don't like Java so I don'tlike JRuby LOL applets Tuesday, September 17, 13
  • 11. Ruby on the JVM JVM SUCKS ROFL AbstractMetaRubyImplementationFactoryFactoryImpl I don't like Java so I don'tlike JRuby LOL applets Tuesday, September 17, 13
  • 12. Welcome to Spain Tuesday, September 17, 13
  • 13. Welcome to Spain Tuesday, September 17, 13
  • 14. Welcome to Spain Tuesday, September 17, 13
  • 15. Welcome to Spain Tuesday, September 17, 13
  • 16. Welcome to Spain Tuesday, September 17, 13
  • 17. Welcome to Spain Tuesday, September 17, 13
  • 18. Welcome to Spain Tuesday, September 17, 13
  • 19. JRuby is Ruby!!! on the JVM... shhh! Tuesday, September 17, 13
  • 20. The Basics • Compatible with Ruby 1.8.7, 1.9.3 • Mostly written in (clean) Java • More and more in Ruby going forward • Entire world of JVM libraries available JVM JDK Classes Other Libraries JRuby Core Classes JRuby Runtime More Core Classes Standard Lib Extras Your Application FFI Tuesday, September 17, 13
  • 21. Roadmap 1.6.0 1.6.1 1.6.2 1.6.3 1.6.7.2 1.7.0.pre1 1.6.4 ... 1.6.8 ... 1.7.3 1.7.4 1.7.5 1.7.6 ... 9000! Next week or two Tuesday, September 17, 13
  • 22. JRuby 9000 really is the next version... 9k ...Coming 2014 Tuesday, September 17, 13
  • 24. 9K Questions • Ruby 2.0 or 2.1-only? • 1.8 support gone • 1.9 support gone • Java 7+ only? • New compiler will be... ? Tuesday, September 17, 13
  • 28. JRuby Team Charlie Tom Nick Hiro Marcin Nahi Wayne Subbu DouglasDouglasContribsDouglas Tuesday, September 17, 13
  • 29. JRuby Team Charlie Tom Nick Hiro Marcin Nahi Wayne Subbu DouglasDouglasContribs DouglasDouglasOpenJDK DouglasDouglasAndroid DouglasDouglasJ9 DouglasDouglasOther JVMs Douglas Tuesday, September 17, 13
  • 30. JVM Over Time 0 7.5 15 22.5 30 Java 1.4 Java 5 Java 6 Java 7 JRuby 1.0.3 (bm_red_black_tree.rb) Tuesday, September 17, 13
  • 31. Versus MRI 1.8 0 7.5 15 22.5 30 Java 1.4 Java 5 Java 6 Java 7 JRuby 1.0.3 (bm_red_black_tree.rb) MRI 1.8 Tuesday, September 17, 13
  • 32. 0ms 75ms 150ms 225ms 300ms 188KB/29MB 27MB/127MB 199MB/238MB Time per GC versus heap usage TimeperGC Heap usage (MRI/JRuby) Ruby 2.0.0 JRuby Tuesday, September 17, 13
  • 33. Features Over Time 1.6 1.8.4 1.8.6 1.8.7 1.9.2 1.9.3 2.0 2.1 Ruby Features JRuby Support Tuesday, September 17, 13
  • 34. However... • JVM development is not fast • JRuby must move forward • Constantly improving Tuesday, September 17, 13
  • 35. What could be better? Performance Native Extensions Concurrency Startup Time Tuesday, September 17, 13
  • 37. Hard to Optimize • Dynamic calls with lots of overhead • Dynamic object structure with indirection • Lots and lots of objects Tuesday, September 17, 13
  • 39. Compile to Bytecode • JVM likes JVM bytecode (surprise!) • Simple compilation of Ruby • Let JVM do the work • Can we do better? Tuesday, September 17, 13
  • 40. Invokedynamic • New JVM feature for languages • Bytecode + IR to describe calls • JVM patches straight through • Optimize any kind of call like Java • Ruby as fast as Java...in theory Tuesday, September 17, 13
  • 42. 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 Tuesday, September 17, 13
  • 43. 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.96s 2.48s red/black tree, pure Ruby versus native Runtime per iteration Tuesday, September 17, 13
  • 44. 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.96s 2.48s 1.39s 1.19s red/black tree, pure Ruby versus native Runtime per iteration Tuesday, September 17, 13
  • 45. 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.96s 2.48s 1.39s 1.19s 0.51s 0.51s 0.51s red/black tree, pure Ruby versus native Runtime per iteration Tuesday, September 17, 13
  • 46. 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.96s 2.48s 1.39s 1.19s 0.51s 0.51s 0.51s 0.29s 0.1s red/black tree, pure Ruby versus native Runtime per iteration Tuesday, September 17, 13
  • 47. But... • Indy was really slow in first Java 7 release • Got fast in 7u2...and turned out broken • Rewritten for 7u40 • Slow to warm up • Getting reports that there's still issues • Java 8 due in March Tuesday, September 17, 13
  • 48. Other Options • New IR compiler/runtime in 9k • Optimize Ruby code before JVM • Specialize types, elide allocations Tuesday, September 17, 13
  • 50. 1 check_arity(2, 0, -1) 2 a(0:0) = recv_pre_reqd_arg(0) 3 thread_poll 4 line_num(2) 5 %v_2 = call(+, a(0:0), [1:Fixnum]) 6 return(%v_2) -Xir.passes=LocalOptimizationPass,DeadCodeElimination def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a(0:0) = recv_pre_reqd_arg(0) 2 b(0:1) = recv_pre_reqd_arg(1) 3 %block(0:2) = recv_closure 4 thread_poll 5 line_num(1) 6 c(0:3) = 1:fixnum 7 line_num(2) 8 %v_0 = call(+, a(0:0), [c(0:3)]) 9 d(0:4) = copy(%v_0) 10 return(%v_0) Optimization propagation Tuesday, September 17, 13
  • 51. Other Options • Truffle/Graal • New compiler backends from Oracle • Graal = direct API to native JIT • Truffle = magic optimizing AST atop Graal • Ruby on Truffle 5x-6x faster than JRuby • But... Tuesday, September 17, 13
  • 52. The Hard Part { Tuesday, September 17, 13
  • 53. Sooo.... • Keep working with JVM guys on InDy • Get our own optimizing compiler done • Explore Graal/Truffle backend • Compiler geeks wanted! :-) Tuesday, September 17, 13
  • 55. 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 Tuesday, September 17, 13
  • 56. 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-way concurrency * 200MB = 2GB Tuesday, September 17, 13
  • 57. 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 100-way concurrency * 200MB = 20GB 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 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 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 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 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 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 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 Tuesday, September 17, 13
  • 58. Multicore in JRuby 300MB JRuby Instance One instance across 10 threads = 300MB Tuesday, September 17, 13
  • 59. Multicore in JRuby 300MB JRuby Instance One instance across 100 threads = 300MB Tuesday, September 17, 13
  • 60. But... • Ruby world is still growing up • Concurrency tools being created • Libraries being made threadsafe • We need to do more to help Tuesday, September 17, 13
  • 61. Unsafe Operations • Concurrent read+write on core structures • Non-atomic updates •@count +=1 •@cache ||= MyCache.new • Thread pooling • Coordinating threads Tuesday, September 17, 13
  • 62. thread_safe • Concurrency-safe Hash • Concurrency-safe Array require 'thread_safe' sa = ThreadSafe::Array.new sh = ThreadSafe::Hash.new Tuesday, September 17, 13
  • 63. hamster • Persistent collections for Ruby • A la Clojure and others simon = Hamster.hash(:name => "Simon", :gender => :male)   simon[:name] # => "Simon" simon.get(:gender) # => :male   james = simon.put(:name, "James") # => {:name => "James", :gender => :male} simon # => {:name => "Simon", :gender => :male} james[:name] # => "James" simon[:name] # => "Simon"   male = simon.delete(:name) # => {:gender => :male} simon # => {:name => "Simon", :gender => :male} male.has_key?(:name) # => false simon.has_key?(:name) # => true Tuesday, September 17, 13
  • 64. atomic • Atomic value holder • Safely update current value • Edit value only if unchanged • Full CPU-level atomicity guarantees Tuesday, September 17, 13
  • 65. 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 my_atomic = Atomic.new(0) my_atomic.update {|v| v + 1} begin my_atomic.try_update {|v| v + 1} rescue Atomic::ConcurrentUpdateError => cue # deal with it (retry, propagate, etc) end Tuesday, September 17, 13
  • 66. jo • Threaded implementation of "goroutines" • "channel" for communication Tuesday, September 17, 13
  • 67. # pinger ponger printer def pinger(c) 20.times { c << 'ping' } end def ponger(c) 20.times { c << 'pong' } end def printer(c) 40.times do puts c.take sleep 1 end end c = chan jo {pinger(c)} # all on separate threads jo {ponger(c)} jo {printer(c)} Tuesday, September 17, 13
  • 68. Bottom Line • Concurrency can work in Ruby • Use the right tools and patterns • Immutability FTW • Test your apps and libs on JRuby! Tuesday, September 17, 13
  • 70. Why Not Ruby? • Performance • Fine grained (lots of calls down to C) • Coarse grained (toss work over the wall) • Library access Tuesday, September 17, 13
  • 71. JRuby 1.6 C Exts • Limited support (now disabled) • Will be moved to external gem • If you want it, support it • Some stuff worked...most didn’t Tuesday, September 17, 13
  • 72. Problems • Performance • Data copying to emulate raw structs • Locking to keep C code thread-safe • Multiple JRuby instances in one JVM • No way from C to know which one • Huge API to support Tuesday, September 17, 13
  • 74. Java Integration • Call Java (Scala, Clojure, ...) from Ruby • Smart mapping of method names • Type conversions as appropriate • Super easy and fun Tuesday, September 17, 13
  • 75. import javax.swing.JFrame import javax.swing.JLable frame = JFrame.new("Window") label = JLabel.new("Hello") frame.add(label) frame.default_close_operation = JFrame::EXIT_ON_CLOSE frame.pack frame.visible = true Tuesday, September 17, 13
  • 76. Java Native Extensions • Similar to C ext for MRI, but with Java • Fast call protocol...basically free • Same GC for all objects • Have to keep in sync if C version too Tuesday, September 17, 13
  • 77. FFI • Ruby API/DSL for calling native code • Runs on all Ruby impls • Maintained by JRuby team! • Solves "access" use case • Works well for coarse-grained calls Tuesday, September 17, 13
  • 78. Ruby FFI example class Timeval < FFI::Struct   layout :tv_sec => :ulong, :tv_usec => :ulong end module LibC   extend FFI::Library   ffi_lib FFI::Library::LIBC   attach_function :gettimeofday, [ :pointer, :pointer ], :int end t = Timeval.new LibC.gettimeofday(t.pointer, nil) Tuesday, September 17, 13
  • 79. But... • Struct binding issues • Across OSes (also 32+64 bit archs) • Across library versions • Library compile option mismatches • Fine-grained perf sometimes suffers Tuesday, September 17, 13
  • 80. Ruby FFI Generator • https://github.com/neelance/ffi-gen • Clang-based Ruby FFI generator • Used to generate clang binding it uses • It's meta! Tuesday, September 17, 13
  • 81. require "ffi/gen" FFI::Gen.generate( module_name: "Clang", ffi_lib: "clang", headers: ["clang-c/Index.h"], cflags: `llvm-config --cflags`.split(" "), prefixes: ["clang_", "CX"], output: "clang-c/index.rb" ) Tuesday, September 17, 13
  • 82.   # A single translation unit, which resides in an index.   class TranslationUnitImpl < FFI::Struct     layout :dummy, :char   end   # Identifies a specific source location within a translation   # unit.   #   # Use clang_getExpansionLocation() or clang_getSpellingLocation()   # to map a source location to a particular file, line, and column.   #   # = Fields:   # :ptr_data ::   # (Array<FFI::Pointer(*Void)>)   # :int_data ::   # (Integer)   class SourceLocation < FFI::Struct     layout :ptr_data, [:pointer, 2],            :int_data, :uint   end Tuesday, September 17, 13
  • 83.   # Retrieves the source location associated with a given file/line/column   # in a particular translation unit.   #   # @method get_location(tu, file, line, column)   # @param [TranslationUnitImpl] tu   # @param [FFI::Pointer(File)] file   # @param [Integer] line   # @param [Integer] column   # @return [SourceLocation]   # @scope class   attach_function :get_location, :clang_getLocation, [TranslationUnitImpl, :pointer, :uint, :uint], SourceLocation.by_value Tuesday, September 17, 13
  • 84. XNI • Ruby + plain old C • Covers access and perf cases • Cross-implementation support • Struct mapping in compile phase • Experimental https://github.com/wmeissner/xni Tuesday, September 17, 13
  • 85. hitimes C Ext /** * call-seq: * interval.start -> boolean * * mark the start of the interval. Calling start on an already started * interval has no effect. An interval can only be started once. If the * interval is truely started +true+ is returned otherwise +false+. */ VALUE hitimes_interval_start( VALUE self ) {     hitimes_interval_t *i;     VALUE rc = Qfalse;     Data_Get_Struct( self, hitimes_interval_t, i );     if ( 0L == i->start_instant ) {       i->start_instant = hitimes_get_current_instant( );       i->stop_instant = 0L;       i->duration = -1.0l;       rc = Qtrue;     }     return rc; } Tuesday, September 17, 13
  • 86. hitimes XNI /** * call-seq: * interval.start -> boolean * * mark the start of the interval. Calling start on an already started * interval has no effect. An interval can only be started once. If the * interval is truely started +true+ is returned otherwise +false+. */ bool hitimes_interval_start( RubyEnv* env, hitimes_interval_t* i ) {     if ( 0L == i->start_instant ) {       i->start_instant = hitimes_get_current_instant( );       i->stop_instant = 0L;       i->duration = -1.0l;       return true;     }     return false; } Tuesday, September 17, 13
  • 88. #1 Pain Point Tuesday, September 17, 13
  • 89. Hard Problem • MRI boot time is 95% native • JRuby boot time is 0% native code • Mostly Java, which needs to warm up • Parser, interpreter, core classes, compiler • Even if our code is better, we start slow Tuesday, September 17, 13
  • 90. Child Processes • Reduce need for sub-Ruby invokes • rails -> clean rails env in child • rails/rake -> bundler relaunch • rake test -> 4+ processes in Rails • rake -> rspec in subprocess • Fix requires changing many libraries Tuesday, September 17, 13
  • 93. Nailgun/Drip • Always running background JVM • Not quite production quality • signals, IO • Small Ruby scripts very fast • Rails not much faster • Lots of requires, objects, boot logic Tuesday, September 17, 13
  • 94. GSoC 2012 IR Persistence IR Instructions CFG DFG ... file.ir file.rb compile file.c compile file.o Tuesday, September 17, 13
  • 95. Reflection on GSoC • Size matters • # of bytes • Intern()‘ing of identifiers matter • Laziness can help a lot Tuesday, September 17, 13
  • 96. Defined vs Used Methods CMD DEFINED USED SAVINGS -e ‘:foo’ 501 33 ~93% gem install rails 1897 529 ~72% rails scaffold 9411 1647 ~82% rake db:migrate 9397 1662 ~82% rake spec 4595 904 ~80% Tuesday, September 17, 13
  • 97. New IR Persistence • Binary format • Constant pool to intern only once per id • (currently once per occurrence) • Incremental loading of method bodies Tuesday, September 17, 13
  • 98. Ultimate Startup! rails new foo JRuby Instance IR Data rails generate JRuby Instance rake db:migrate JRuby Instance Compile Use Use Background JVM Tuesday, September 17, 13
  • 99. Ruby is Strong • Still growing and improving • MRI too! • Concurrency can be done • C extensions are holding us back • Never surrender! Tuesday, September 17, 13
  • 100. ThankYou! • Charles Oliver Nutter • @headius • headius@headius.com • http://blog.headius.com Tuesday, September 17, 13