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
Douglas Douglas Contribs Douglas Douglas OpenJDK Douglas Douglas Android Douglas Douglas J9 Douglas Douglas Other JVMs Douglas Tuesday, September 17, 13
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
• 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
= 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
'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
• 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
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
and perf cases • Cross-implementation support • Struct mapping in compile phase • Experimental https://github.com/wmeissner/xni Tuesday, September 17, 13
* * 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
* 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
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