SlideShare a Scribd company logo
1 of 65
Download to read offline
JRuby 9000
Optimizing Above the JVM
Me
• Charles Oliver Nutter (@headius)
• Red Hat
• Based in Minneapolis, Minnesota
• Ten years working on JRuby (uff da!)
Ruby Challenges
• Dynamic dispatch for most things
• Dynamic possibly-mutating constants
• Fixnum to Bignum promotion
• Literals for arrays, hashes: [a, b, c].sort[1]
• Stack access via closures, bindings
• Rich inheritance model
module SayHello

def say_hello

"Hello, " + to_s

end

end



class Foo

include SayHello



def initialize

@my_data = {bar: 'baz', quux: 'widget'}

end



def to_s

@my_data.map do |k,v|

"#{k} = #{v}"

end.join(', ')

end

end



Foo.new.say_hello # => "Hello, bar = baz, quux = widget"
More Challenges
• "Everything's an object"
• Tracing and debugging APIs
• Pervasive use of closures
• Mutable literal strings
JRuby 9000
• Mixed mode runtime (now with tiers!)
• Lazy JIT to JVM bytecode
• byte[] strings and regular expressions
• Lots of native integration via FFI
• 9.0.5.0 is current
New IR
• Optimizable intermediate representation
• AST to semantic IR
• Traditional compiler design
• Register machine
• SSA-ish where it's useful
Lexical
Analysis
Parsing
Semantic
Analysis
Optimization
Bytecode
Generation
Interpret
AST
IR Instructions
CFG DFG ...
JRuby 1.7.x
9000+
Bytecode
Generation
Interpret
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
2 b = recv_pre_reqd_arg(1)
3 %block = recv_closure
4 thread_poll
5 line_num(1)
6 c = 1
7 line_num(2)
8 %v_0 = call(:+, a, [c])
9 d = copy(%v_0)
10 return(%v_0)
Register-based
3 address format
IR InstructionsSemantic
Analysis
-Xir.passes=LocalOptimizationPass,
DeadCodeElimination
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
2 b = recv_pre_reqd_arg(1)
3 %block = recv_closure
4 thread_poll
5 line_num(1)
6 c = 1
7 line_num(2)
8 %v_0 = call(:+, a, [c])
9 d = copy(%v_0)
10 return(%v_0)
Optimization
-Xir.passes=LocalOptimizationPass,
DeadCodeElimination
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
2 b = recv_pre_reqd_arg(1)
3 %block = recv_closure
4 thread_poll
5 line_num(1)
6 c = 1
7 line_num(2)
8 %v_0 = call(:+, a, [c])
9 d = copy(%v_0)
10 return(%v_0)
Optimization
-Xir.passes=LocalOptimizationPass,
DeadCodeElimination
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
2 b = recv_pre_reqd_arg(1)
3 %block = recv_closure
4 thread_poll
5 line_num(1)
6 c = 1
7 line_num(2)
8 %v_0 = call(:+, a, [c])
9 d = copy(%v_0)
10 return(%v_0)
Optimization
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
4 thread_poll
5 line_num(1)
6 c = 1
7 line_num(2)
8 %v_0 = call(:+, a, [c])
9 d = copy(%v_0)
10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass,
DeadCodeElimination
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
4 thread_poll
5 line_num(1)
6 c = 1
7 line_num(2)
8 %v_0 = call(:+, a, [c])
9 d = copy(%v_0)
10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass,
DeadCodeElimination
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
4 thread_poll
5 line_num(1)
6 c = 1
7 line_num(2)
8 %v_0 = call(:+, a, [c])
9 d = copy(%v_0)
10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass,
DeadCodeElimination
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
4 thread_poll
5 line_num(1)
6 c =
7 line_num(2)
8 %v_0 = call(:+, a, [ ])
9 d = copy(%v_0)
10 return(%v_0)
1
Optimization -Xir.passes=LocalOptimizationPass,
DeadCodeElimination
def foo(a, b)
c = 1
d = a + c
end
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
4 thread_poll
5 line_num(1)
7 line_num(2)
8 %v_0 = call(:+, a, [1])
9 d = copy(%v_0)
10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass,
DeadCodeElimination
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
4 thread_poll
5 line_num(1)
7 line_num(2)
8 %v_0 = call(:+, a, [1])
9 d = copy(%v_0)
10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass,
DeadCodeElimination
0 check_arity(2, 0, -1)
1 a = recv_pre_reqd_arg(0)
4 thread_poll
7 line_num(2)
8 %v_0 = call(:+, a, [1])
9 d = copy(%v_0)
10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass,
DeadCodeElimination
Tiers in the Rain
• Tier 1: Simple interpreter (no passes run)
• Tier 2: Full interpreter (static optimization)
• Tier 3: Full interpreter (profiled optz)
• Tier 4: JVM bytecode (static)
• Tier 5: JVM bytecode (profiled)
• Tiers 6+:Whatever JVM does from there
Truffle?
• Write your AST + specializations
• AST rewrites as it runs
• Eventually emits Graal IR (i.e. not JVM)
• Very fast peak perf on benchmarks
• Poor startup, warmup, memory use
• Year(s) left until generally usable
Red/black tree benchmark
0
2.25
4.5
6.75
9
JRuby int JRuby no indy JRuby with indy
JRuby+Truffle CRuby 2.3
Why Not Just JVM?
• JVM is great, but missing many things
• I'll mention some along the way
Current Optimizations
Block Jitting
• JRuby 1.7 only jitted methods
• Not free-standing procs/lambdas
• Not define_method blocks
• Easier to do now with 9000's IR
• Blocks JIT as of 9.0.4.0
define_method
Convenient for metaprogramming,
but blocks have more overhead than methods.
define_method(:add) do |a, b|

a + b

end
names.each do |name|

define_method(name) { send :"do_#{name}" }

end
Optimizing define_method
• Noncapturing
• Treat as method in compiler
• Ignore surrounding scope
• Capturing (future work)
• Lift read-only variables as constant
Getting Better!
0k iters/s
1000k iters/s
2000k iters/s
3000k iters/s
4000k iters/s
def define_method define_method w/ capture
MRI JRuby 9.0.1.0 JRuby 9.0.4.0
JVM?
• Missing feature: access to call frames
• No way to expose local variables
• Therefore, have to use heap
• Allocation, loss of locality
Low-cost Exceptions
• Backtrace cost isVERY high on JVM
• Lots of work to construct
• Exceptions frequently ignored
• ...or used as flow control (shame!)
• If ignored, backtrace is not needed!
Postfix Antipattern
foo rescue nil
Exception raised
StandardError rescued
Exception ignored
Result is simple expression, so exception is never visible.
csv.rb Converters
Converters = { integer: lambda { |f|

Integer(f) rescue f

},

float: lambda { |f|

Float(f) rescue f

},

...
All trivial rescues, no traces needed.
Strategy
• Inspect rescue block
• If simple expression...
• Thread-local requiresBacktrace = false
• Backtrace generation short circuited
• Reset to true on exit or nontrivial rescue
Simple rescue
Improvement
0
150000
300000
450000
600000
Iters/second
524,475
10,700
Much Better!
1
10
100
1000
10000
100000
1000000
Iters/second
524,475
10,700
JVM?
• Horrific cost for stack traces
• Only eliminated if inlined
• Disabling is not really an option
Work In Progress
Object Shaping
• Ruby instance vars allocated dynamically
• JRuby currently grows an array
• We have code to specialize as fields
• Working, tested
• Probably next release
public class RubyObjectVar2 extends ReifiedRubyObject {

private Object var0;

private Object var1;

private Object var2;

public RubyObjectVar2(Ruby runtime, RubyClass metaClass) {

super(runtime, metaClass);

}



@Override

public Object getVariable(int i) {

switch (i) {

case 0: return var0;

case 1: return var1;

case 2: return var2;

default: return super.getVariable(i);

}

}



public Object getVariable0() {

return var0;

}

...


public void setVariable0(Object value) {

ensureInstanceVariablesSettable();

var0 = value;

}
...


}
JVM?
• No way to truly generify fields
• Valhalla will be useful here
• No way to grow an object
Inlining
• 900 pound gorilla of optimization
• shove method/closure back to callsite
• specialize closure-receiving methods
• eliminate call protocol
• We know Ruby better than the JVM
JVM?
• JVM will inline for us, but...
• only if we use invokedynamic
• and the code isn't too big
• and it's not polymorphic
• and we're not a closure (lambdas too!)
• and it feels like it
Today’s Inliner
def decrement_one(i)
i - 1
end
i = 1_000_000
while i > 0
i = decrement_one(i)
end
def decrement_one(i)
i - 1
end
i = 1_000_000
while i < 0
if guard_same? self
i = i - 1
else
i = decrement_one(i)
end
end
Today’s Inliner
def decrement_one(i)
i - 1
end
i = 1_000_000
while i > 0
i = decrement_one(i)
end
def decrement_one(i)
i - 1
end
i = 1_000_000
while i < 0
if guard_same? self
i = i - 1
else
i = decrement_one(i)
end
end
Today’s Inliner
def decrement_one(i)
i - 1
end
i = 1_000_000
while i > 0
i = decrement_one(i)
end
def decrement_one(i)
i - 1
end
i = 1_000_000
while i < 0
if guard_same? self
i = i - 1
else
i = decrement_one(i)
end
end
Today’s Inliner
def decrement_one(i)
i - 1
end
i = 1_000_000
while i > 0
i = decrement_one(i)
end
def decrement_one(i)
i - 1
end
i = 1_000_000
while i < 0
if guard_same? self
i = i - 1
else
i = decrement_one(i)
end
end
Profiling
• You can't inline if you can't profile!
• For each call site record call info
• Which method(s) called
• How frequently
• Inline most frequently-called method
Inlining a Closure
def small_loop(i)
k = 10
while k > 0
k = yield(k)
end
i - 1
end
def big_loop(i)
i = 100_000
while true
i = small_loop(i) { |j| j - 1 }
return 0 if i < 0
end
end
900.times { |i| big_loop i }
hot & monomorphic
Like an Array#each
May see many blocks
JVM will not inline this
Inlining FTW!
0
15
30
45
60
Time in seconds
14.1
56.9
Profiling
• <2% overhead (to be reduced more)
• Working* (interpreter AND JIT)
• Feeds directly into inlining
• Deopt coming soon
* Fragile and buggy!
Interpreter FTW!
• Deopt is much simpler with interpreter
• Collect local vars, instruction index
• Raise exception to interpreter, keep going
• Much cheaper than resuming bytecode
Numeric Specialization
• "Unboxing"
• Ruby: everything's an object
• Tagged pointer for Fixnum, Float
• JVM: references OR primitives
• Need to optimize numerics as primitive
JVM?
• Escape analysis is inadequate (today)
• Hotspot will eliminate boxes if...
• All code inlines
• No (unfollowed?) branches in the code
• Dynamic calls have type guards
• Fixnum + Fixnum has overflow check
def looper(n)

i = 0

while i < n

do_something(i)

i += 1

end

end
def looper(long n)

long i = 0

while i < n

do_something(i)

i += 1

end

end
Specialize n, i to long
def looper(n)

i = 0

while i < n

do_something(i)

i += 1

end

end
Deopt to object version if n or i + 1 is not Fixnum
Unboxing Today
• Working prototype
• No deopt
• No type guards
• No overflow check for Fixnum/Bignum
Rendering
*
*
*
*
*
***
*****
*****
***
*
*********
*************
***************
*********************
*********************
*******************
*******************
*******************
*******************
***********************
*******************
*******************
*********************
*******************
*******************
*****************
***************
*************
*********
*
***************
***********************
* ************************* *
*****************************
* ******************************* *
*********************************
***********************************
***************************************
*** ***************************************** ***
*************************************************
***********************************************
*********************************************
*********************************************
***********************************************
***********************************************
***************************************************
*************************************************
*************************************************
***************************************************
***************************************************
* *************************************************** *
***** *************************************************** *****
****** *************************************************** ******
******* *************************************************** *******
***********************************************************************
********* *************************************************** *********
****** *************************************************** ******
***** *************************************************** *****
***************************************************
***************************************************
***************************************************
***************************************************
*************************************************
*************************************************
***************************************************
***********************************************
***********************************************
*******************************************
*****************************************
*********************************************
**** ****************** ****************** ****
*** **************** **************** ***
* ************** ************** *
*********** ***********
** ***** ***** **
* * * *
0.520000 0.020000 0.540000 ( 0.388744)
def iterate(x,y)

cr = y-0.5

ci = x

zi = 0.0

zr = 0.0

i = 0

bailout = 16.0

max_iterations = 1000



while true

i += 1

temp = zr * zi

zr2 = zr * zr

zi2 = zi * zi

zr = zr2 - zi2 + cr

zi = temp + temp + ci

return i if (zi2 + zr2 > bailout)

return 0 if (i > max_iterations)

end

end
Mandelbrot performance
0
0.075
0.15
0.225
0.3
JRuby JRuby + truffle
Mandelbrot performance
0
0.075
0.15
0.225
0.3
JRuby JRuby + truffle JRuby on Graal
Mandelbrot performance
0
0.035
0.07
0.105
0.14
JRuby + truffle JRuby on Graal JRuby unbox
When?
• Object shape should be in 9.1
• Profiling, inlining mostly need testing
• Specialization needs guards, deopt
• Active work over next 6-12mo
Summary
• JVM is great, but we need more
• Partial EA, frame access, specialization
• Gotta stay ahead of these youngsters!
• JRuby 9000 is aVM on top of aVM
• We believe we can match Truffle
• (for a large range of optimizations)
ThankYou
• Charles Oliver Nutter
• @headius
• headius@headius.com

More Related Content

What's hot

JavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesJavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesCharles Nutter
 
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)ngotogenome
 
これからのPerlプロダクトのかたち(YAPC::Asia 2013)
これからのPerlプロダクトのかたち(YAPC::Asia 2013)これからのPerlプロダクトのかたち(YAPC::Asia 2013)
これからのPerlプロダクトのかたち(YAPC::Asia 2013)goccy
 
JRuby @ Boulder Ruby
JRuby @ Boulder RubyJRuby @ Boulder Ruby
JRuby @ Boulder RubyNick Sieger
 
Implementing a JavaScript Engine
Implementing a JavaScript EngineImplementing a JavaScript Engine
Implementing a JavaScript EngineKris Mok
 
JVM JIT-compiler overview @ JavaOne Moscow 2013
JVM JIT-compiler overview @ JavaOne Moscow 2013JVM JIT-compiler overview @ JavaOne Moscow 2013
JVM JIT-compiler overview @ JavaOne Moscow 2013Vladimir Ivanov
 
Mastering java bytecode with ASM - GeeCON 2012
Mastering java bytecode with ASM - GeeCON 2012Mastering java bytecode with ASM - GeeCON 2012
Mastering java bytecode with ASM - GeeCON 2012Anton Arhipov
 
Why scala is not my ideal language and what I can do with this
Why scala is not my ideal language and what I can do with thisWhy scala is not my ideal language and what I can do with this
Why scala is not my ideal language and what I can do with thisRuslan Shevchenko
 
Ø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
 
Java & low latency applications
Java & low latency applicationsJava & low latency applications
Java & low latency applicationsRuslan Shevchenko
 
Concurrency in Python
Concurrency in PythonConcurrency in Python
Concurrency in PythonMosky Liu
 
RubyKaigi2015 making robots-with-mruby
RubyKaigi2015 making robots-with-mrubyRubyKaigi2015 making robots-with-mruby
RubyKaigi2015 making robots-with-mrubyyamanekko
 
Building High Performance Android Applications in Java and C++
Building High Performance Android Applications in Java and C++Building High Performance Android Applications in Java and C++
Building High Performance Android Applications in Java and C++Kenneth Geisshirt
 
Clojure in real life 17.10.2014
Clojure in real life 17.10.2014Clojure in real life 17.10.2014
Clojure in real life 17.10.2014Metosin Oy
 
Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013Charles Nutter
 
Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?Mario Camou Riveroll
 
Asynchronous I/O in Python 3
Asynchronous I/O in Python 3Asynchronous I/O in Python 3
Asynchronous I/O in Python 3Feihong Hsu
 
2008 07-24 kwpm-threads_and_synchronization
2008 07-24 kwpm-threads_and_synchronization2008 07-24 kwpm-threads_and_synchronization
2008 07-24 kwpm-threads_and_synchronizationfangjiafu
 

What's hot (20)

JavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesJavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for Dummies
 
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
 
Down the Rabbit Hole
Down the Rabbit HoleDown the Rabbit Hole
Down the Rabbit Hole
 
これからのPerlプロダクトのかたち(YAPC::Asia 2013)
これからのPerlプロダクトのかたち(YAPC::Asia 2013)これからのPerlプロダクトのかたち(YAPC::Asia 2013)
これからのPerlプロダクトのかたち(YAPC::Asia 2013)
 
Ruby 2.4 Internals
Ruby 2.4 InternalsRuby 2.4 Internals
Ruby 2.4 Internals
 
JRuby @ Boulder Ruby
JRuby @ Boulder RubyJRuby @ Boulder Ruby
JRuby @ Boulder Ruby
 
Implementing a JavaScript Engine
Implementing a JavaScript EngineImplementing a JavaScript Engine
Implementing a JavaScript Engine
 
JVM JIT-compiler overview @ JavaOne Moscow 2013
JVM JIT-compiler overview @ JavaOne Moscow 2013JVM JIT-compiler overview @ JavaOne Moscow 2013
JVM JIT-compiler overview @ JavaOne Moscow 2013
 
Mastering java bytecode with ASM - GeeCON 2012
Mastering java bytecode with ASM - GeeCON 2012Mastering java bytecode with ASM - GeeCON 2012
Mastering java bytecode with ASM - GeeCON 2012
 
Why scala is not my ideal language and what I can do with this
Why scala is not my ideal language and what I can do with thisWhy scala is not my ideal language and what I can do with this
Why scala is not my ideal language and what I can do with this
 
Ø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 ...
 
Java & low latency applications
Java & low latency applicationsJava & low latency applications
Java & low latency applications
 
Concurrency in Python
Concurrency in PythonConcurrency in Python
Concurrency in Python
 
RubyKaigi2015 making robots-with-mruby
RubyKaigi2015 making robots-with-mrubyRubyKaigi2015 making robots-with-mruby
RubyKaigi2015 making robots-with-mruby
 
Building High Performance Android Applications in Java and C++
Building High Performance Android Applications in Java and C++Building High Performance Android Applications in Java and C++
Building High Performance Android Applications in Java and C++
 
Clojure in real life 17.10.2014
Clojure in real life 17.10.2014Clojure in real life 17.10.2014
Clojure in real life 17.10.2014
 
Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013
 
Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?
 
Asynchronous I/O in Python 3
Asynchronous I/O in Python 3Asynchronous I/O in Python 3
Asynchronous I/O in Python 3
 
2008 07-24 kwpm-threads_and_synchronization
2008 07-24 kwpm-threads_and_synchronization2008 07-24 kwpm-threads_and_synchronization
2008 07-24 kwpm-threads_and_synchronization
 

Viewers also liked

Save the date MBA REFRESHER
Save the date MBA REFRESHERSave the date MBA REFRESHER
Save the date MBA REFRESHERclementwasselin
 
Codes and conventions of a music magazine contents
Codes and conventions of a music magazine contentsCodes and conventions of a music magazine contents
Codes and conventions of a music magazine contentsEllie Niccolls
 
CommunicationFundamentals_CertificateOfCompletion (1)
CommunicationFundamentals_CertificateOfCompletion (1)CommunicationFundamentals_CertificateOfCompletion (1)
CommunicationFundamentals_CertificateOfCompletion (1)Susan Smith
 
ntv linked in
ntv linked inntv linked in
ntv linked innoel ver
 
Nashorn on JDK 8 (ADC2013)
Nashorn on JDK 8 (ADC2013)Nashorn on JDK 8 (ADC2013)
Nashorn on JDK 8 (ADC2013)Kris Mok
 
5 Simple Ways to keep your Heart Healthy!
5 Simple Ways to keep your Heart Healthy!5 Simple Ways to keep your Heart Healthy!
5 Simple Ways to keep your Heart Healthy!akajay201988
 
Apache Big_Data Europe event: "Demonstrating the Societal Value of Big & Smar...
Apache Big_Data Europe event: "Demonstrating the Societal Value of Big & Smar...Apache Big_Data Europe event: "Demonstrating the Societal Value of Big & Smar...
Apache Big_Data Europe event: "Demonstrating the Societal Value of Big & Smar...BigData_Europe
 
Exámenes de docentes2
Exámenes de docentes2Exámenes de docentes2
Exámenes de docentes2Oscar Sanchez
 

Viewers also liked (13)

Save the date MBA REFRESHER
Save the date MBA REFRESHERSave the date MBA REFRESHER
Save the date MBA REFRESHER
 
Codes and conventions of a music magazine contents
Codes and conventions of a music magazine contentsCodes and conventions of a music magazine contents
Codes and conventions of a music magazine contents
 
Final Draft HTM 4964
Final Draft HTM 4964Final Draft HTM 4964
Final Draft HTM 4964
 
CommunicationFundamentals_CertificateOfCompletion (1)
CommunicationFundamentals_CertificateOfCompletion (1)CommunicationFundamentals_CertificateOfCompletion (1)
CommunicationFundamentals_CertificateOfCompletion (1)
 
E-Biz Marketing Plan
E-Biz Marketing PlanE-Biz Marketing Plan
E-Biz Marketing Plan
 
ntv linked in
ntv linked inntv linked in
ntv linked in
 
What's in a Name?
What's in a Name?What's in a Name?
What's in a Name?
 
Nashorn on JDK 8 (ADC2013)
Nashorn on JDK 8 (ADC2013)Nashorn on JDK 8 (ADC2013)
Nashorn on JDK 8 (ADC2013)
 
5 Simple Ways to keep your Heart Healthy!
5 Simple Ways to keep your Heart Healthy!5 Simple Ways to keep your Heart Healthy!
5 Simple Ways to keep your Heart Healthy!
 
War of deodorants
War of deodorantsWar of deodorants
War of deodorants
 
Apache Big_Data Europe event: "Demonstrating the Societal Value of Big & Smar...
Apache Big_Data Europe event: "Demonstrating the Societal Value of Big & Smar...Apache Big_Data Europe event: "Demonstrating the Societal Value of Big & Smar...
Apache Big_Data Europe event: "Demonstrating the Societal Value of Big & Smar...
 
Motivación
MotivaciónMotivación
Motivación
 
Exámenes de docentes2
Exámenes de docentes2Exámenes de docentes2
Exámenes de docentes2
 

Similar to JRuby 9000 - Optimizing Above the JVM

JavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesJavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesCharles Nutter
 
Rubinius @ RubyAndRails2010
Rubinius @ RubyAndRails2010Rubinius @ RubyAndRails2010
Rubinius @ RubyAndRails2010Dirkjan Bussink
 
Rubinius 1.0 and more!
Rubinius 1.0 and more!Rubinius 1.0 and more!
Rubinius 1.0 and more!evanphx
 
Ruby is an Acceptable Lisp
Ruby is an Acceptable LispRuby is an Acceptable Lisp
Ruby is an Acceptable LispAstrails
 
Python高级编程(二)
Python高级编程(二)Python高级编程(二)
Python高级编程(二)Qiangning Hong
 
GoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPHGoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPHGautam Rege
 
Groovy presentation
Groovy presentationGroovy presentation
Groovy presentationManav Prasad
 
Code lifecycle in the jvm - TopConf Linz
Code lifecycle in the jvm - TopConf LinzCode lifecycle in the jvm - TopConf Linz
Code lifecycle in the jvm - TopConf LinzIvan Krylov
 
Functional Programming in Javascript - IL Tech Talks week
Functional Programming in Javascript - IL Tech Talks weekFunctional Programming in Javascript - IL Tech Talks week
Functional Programming in Javascript - IL Tech Talks weekyoavrubin
 
Vim Script Programming
Vim Script ProgrammingVim Script Programming
Vim Script ProgrammingLin Yo-An
 
Invoke dynamic your api to hotspot
Invoke dynamic your api to hotspotInvoke dynamic your api to hotspot
Invoke dynamic your api to hotspotBoundary
 
Building High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortBuilding High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortStefan Marr
 
Some Rough Fibrous Material
Some Rough Fibrous MaterialSome Rough Fibrous Material
Some Rough Fibrous MaterialMurray Steele
 

Similar to JRuby 9000 - Optimizing Above the JVM (20)

There and Back Again
There and Back AgainThere and Back Again
There and Back Again
 
JavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesJavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for Dummies
 
Rubinius @ RubyAndRails2010
Rubinius @ RubyAndRails2010Rubinius @ RubyAndRails2010
Rubinius @ RubyAndRails2010
 
Rubinius 1.0 and more!
Rubinius 1.0 and more!Rubinius 1.0 and more!
Rubinius 1.0 and more!
 
Ruby is an Acceptable Lisp
Ruby is an Acceptable LispRuby is an Acceptable Lisp
Ruby is an Acceptable Lisp
 
Python高级编程(二)
Python高级编程(二)Python高级编程(二)
Python高级编程(二)
 
GoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPHGoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPH
 
MacRuby, an introduction
MacRuby, an introductionMacRuby, an introduction
MacRuby, an introduction
 
Jvm memory model
Jvm memory modelJvm memory model
Jvm memory model
 
Run Node Run
Run Node RunRun Node Run
Run Node Run
 
Groovy presentation
Groovy presentationGroovy presentation
Groovy presentation
 
Appsec obfuscator reloaded
Appsec obfuscator reloadedAppsec obfuscator reloaded
Appsec obfuscator reloaded
 
Code lifecycle in the jvm - TopConf Linz
Code lifecycle in the jvm - TopConf LinzCode lifecycle in the jvm - TopConf Linz
Code lifecycle in the jvm - TopConf Linz
 
Functional Programming in Javascript - IL Tech Talks week
Functional Programming in Javascript - IL Tech Talks weekFunctional Programming in Javascript - IL Tech Talks week
Functional Programming in Javascript - IL Tech Talks week
 
Why MacRuby Matters
Why MacRuby MattersWhy MacRuby Matters
Why MacRuby Matters
 
Vim Script Programming
Vim Script ProgrammingVim Script Programming
Vim Script Programming
 
Invoke dynamic your api to hotspot
Invoke dynamic your api to hotspotInvoke dynamic your api to hotspot
Invoke dynamic your api to hotspot
 
Building High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortBuilding High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low Effort
 
Some Rough Fibrous Material
Some Rough Fibrous MaterialSome Rough Fibrous Material
Some Rough Fibrous Material
 
New features in Ruby 2.5
New features in Ruby 2.5New features in Ruby 2.5
New features in Ruby 2.5
 

More from Charles 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! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013Beyond JVM - YOW! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013Charles Nutter
 
The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013Charles Nutter
 
High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013Charles Nutter
 
Invokedynamic in 45 Minutes
Invokedynamic in 45 MinutesInvokedynamic in 45 Minutes
Invokedynamic in 45 MinutesCharles Nutter
 
Invokedynamic: Tales from the Trenches
Invokedynamic: Tales from the TrenchesInvokedynamic: Tales from the Trenches
Invokedynamic: Tales from the TrenchesCharles Nutter
 
Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012Charles Nutter
 
Aloha RubyConf 2012 - JRuby
Aloha RubyConf 2012 - JRubyAloha RubyConf 2012 - JRuby
Aloha RubyConf 2012 - JRubyCharles 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
 
Building Languages for the JVM - StarTechConf 2011
Building Languages for the JVM - StarTechConf 2011Building Languages for the JVM - StarTechConf 2011
Building Languages for the JVM - StarTechConf 2011Charles Nutter
 
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
 

More from Charles Nutter (18)

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! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013Beyond JVM - YOW! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013
 
The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013
 
High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013
 
Invokedynamic in 45 Minutes
Invokedynamic in 45 MinutesInvokedynamic in 45 Minutes
Invokedynamic in 45 Minutes
 
Invokedynamic: Tales from the Trenches
Invokedynamic: Tales from the TrenchesInvokedynamic: Tales from the Trenches
Invokedynamic: Tales from the Trenches
 
Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012Why JRuby? - RubyConf 2012
Why JRuby? - RubyConf 2012
 
Aloha RubyConf 2012 - JRuby
Aloha RubyConf 2012 - JRubyAloha RubyConf 2012 - JRuby
Aloha RubyConf 2012 - JRuby
 
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
 
Building Languages for the JVM - StarTechConf 2011
Building Languages for the JVM - StarTechConf 2011Building Languages for the JVM - StarTechConf 2011
Building Languages for the JVM - StarTechConf 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)
JRuby: What's Different (RORO Melbourne October 2011)
 

Recently uploaded

Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...aditisharan08
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 

Recently uploaded (20)

Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 

JRuby 9000 - Optimizing Above the JVM

  • 2. Me • Charles Oliver Nutter (@headius) • Red Hat • Based in Minneapolis, Minnesota • Ten years working on JRuby (uff da!)
  • 3. Ruby Challenges • Dynamic dispatch for most things • Dynamic possibly-mutating constants • Fixnum to Bignum promotion • Literals for arrays, hashes: [a, b, c].sort[1] • Stack access via closures, bindings • Rich inheritance model
  • 4. module SayHello
 def say_hello
 "Hello, " + to_s
 end
 end
 
 class Foo
 include SayHello
 
 def initialize
 @my_data = {bar: 'baz', quux: 'widget'}
 end
 
 def to_s
 @my_data.map do |k,v|
 "#{k} = #{v}"
 end.join(', ')
 end
 end
 
 Foo.new.say_hello # => "Hello, bar = baz, quux = widget"
  • 5. More Challenges • "Everything's an object" • Tracing and debugging APIs • Pervasive use of closures • Mutable literal strings
  • 6. JRuby 9000 • Mixed mode runtime (now with tiers!) • Lazy JIT to JVM bytecode • byte[] strings and regular expressions • Lots of native integration via FFI • 9.0.5.0 is current
  • 7. New IR • Optimizable intermediate representation • AST to semantic IR • Traditional compiler design • Register machine • SSA-ish where it's useful
  • 9. def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 2 b = recv_pre_reqd_arg(1) 3 %block = recv_closure 4 thread_poll 5 line_num(1) 6 c = 1 7 line_num(2) 8 %v_0 = call(:+, a, [c]) 9 d = copy(%v_0) 10 return(%v_0) Register-based 3 address format IR InstructionsSemantic Analysis
  • 10. -Xir.passes=LocalOptimizationPass, DeadCodeElimination def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 2 b = recv_pre_reqd_arg(1) 3 %block = recv_closure 4 thread_poll 5 line_num(1) 6 c = 1 7 line_num(2) 8 %v_0 = call(:+, a, [c]) 9 d = copy(%v_0) 10 return(%v_0) Optimization
  • 11. -Xir.passes=LocalOptimizationPass, DeadCodeElimination def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 2 b = recv_pre_reqd_arg(1) 3 %block = recv_closure 4 thread_poll 5 line_num(1) 6 c = 1 7 line_num(2) 8 %v_0 = call(:+, a, [c]) 9 d = copy(%v_0) 10 return(%v_0) Optimization
  • 12. -Xir.passes=LocalOptimizationPass, DeadCodeElimination def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 2 b = recv_pre_reqd_arg(1) 3 %block = recv_closure 4 thread_poll 5 line_num(1) 6 c = 1 7 line_num(2) 8 %v_0 = call(:+, a, [c]) 9 d = copy(%v_0) 10 return(%v_0) Optimization
  • 13. def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 4 thread_poll 5 line_num(1) 6 c = 1 7 line_num(2) 8 %v_0 = call(:+, a, [c]) 9 d = copy(%v_0) 10 return(%v_0) Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
  • 14. def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 4 thread_poll 5 line_num(1) 6 c = 1 7 line_num(2) 8 %v_0 = call(:+, a, [c]) 9 d = copy(%v_0) 10 return(%v_0) Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
  • 15. def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 4 thread_poll 5 line_num(1) 6 c = 1 7 line_num(2) 8 %v_0 = call(:+, a, [c]) 9 d = copy(%v_0) 10 return(%v_0) Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
  • 16. def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 4 thread_poll 5 line_num(1) 6 c = 7 line_num(2) 8 %v_0 = call(:+, a, [ ]) 9 d = copy(%v_0) 10 return(%v_0) 1 Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
  • 17. def foo(a, b) c = 1 d = a + c end 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 4 thread_poll 5 line_num(1) 7 line_num(2) 8 %v_0 = call(:+, a, [1]) 9 d = copy(%v_0) 10 return(%v_0) Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
  • 18. 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 4 thread_poll 5 line_num(1) 7 line_num(2) 8 %v_0 = call(:+, a, [1]) 9 d = copy(%v_0) 10 return(%v_0) Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
  • 19. 0 check_arity(2, 0, -1) 1 a = recv_pre_reqd_arg(0) 4 thread_poll 7 line_num(2) 8 %v_0 = call(:+, a, [1]) 9 d = copy(%v_0) 10 return(%v_0) Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
  • 20. Tiers in the Rain • Tier 1: Simple interpreter (no passes run) • Tier 2: Full interpreter (static optimization) • Tier 3: Full interpreter (profiled optz) • Tier 4: JVM bytecode (static) • Tier 5: JVM bytecode (profiled) • Tiers 6+:Whatever JVM does from there
  • 21. Truffle? • Write your AST + specializations • AST rewrites as it runs • Eventually emits Graal IR (i.e. not JVM) • Very fast peak perf on benchmarks • Poor startup, warmup, memory use • Year(s) left until generally usable
  • 22. Red/black tree benchmark 0 2.25 4.5 6.75 9 JRuby int JRuby no indy JRuby with indy JRuby+Truffle CRuby 2.3
  • 23. Why Not Just JVM? • JVM is great, but missing many things • I'll mention some along the way
  • 25. Block Jitting • JRuby 1.7 only jitted methods • Not free-standing procs/lambdas • Not define_method blocks • Easier to do now with 9000's IR • Blocks JIT as of 9.0.4.0
  • 26. define_method Convenient for metaprogramming, but blocks have more overhead than methods. define_method(:add) do |a, b|
 a + b
 end names.each do |name|
 define_method(name) { send :"do_#{name}" }
 end
  • 27. Optimizing define_method • Noncapturing • Treat as method in compiler • Ignore surrounding scope • Capturing (future work) • Lift read-only variables as constant
  • 28. Getting Better! 0k iters/s 1000k iters/s 2000k iters/s 3000k iters/s 4000k iters/s def define_method define_method w/ capture MRI JRuby 9.0.1.0 JRuby 9.0.4.0
  • 29. JVM? • Missing feature: access to call frames • No way to expose local variables • Therefore, have to use heap • Allocation, loss of locality
  • 30. Low-cost Exceptions • Backtrace cost isVERY high on JVM • Lots of work to construct • Exceptions frequently ignored • ...or used as flow control (shame!) • If ignored, backtrace is not needed!
  • 31. Postfix Antipattern foo rescue nil Exception raised StandardError rescued Exception ignored Result is simple expression, so exception is never visible.
  • 32. csv.rb Converters Converters = { integer: lambda { |f|
 Integer(f) rescue f
 },
 float: lambda { |f|
 Float(f) rescue f
 },
 ... All trivial rescues, no traces needed.
  • 33. Strategy • Inspect rescue block • If simple expression... • Thread-local requiresBacktrace = false • Backtrace generation short circuited • Reset to true on exit or nontrivial rescue
  • 36. JVM? • Horrific cost for stack traces • Only eliminated if inlined • Disabling is not really an option
  • 38. Object Shaping • Ruby instance vars allocated dynamically • JRuby currently grows an array • We have code to specialize as fields • Working, tested • Probably next release
  • 39. public class RubyObjectVar2 extends ReifiedRubyObject {
 private Object var0;
 private Object var1;
 private Object var2;
 public RubyObjectVar2(Ruby runtime, RubyClass metaClass) {
 super(runtime, metaClass);
 }
 
 @Override
 public Object getVariable(int i) {
 switch (i) {
 case 0: return var0;
 case 1: return var1;
 case 2: return var2;
 default: return super.getVariable(i);
 }
 }
 
 public Object getVariable0() {
 return var0;
 }
 ... 
 public void setVariable0(Object value) {
 ensureInstanceVariablesSettable();
 var0 = value;
 } ... 
 }
  • 40. JVM? • No way to truly generify fields • Valhalla will be useful here • No way to grow an object
  • 41. Inlining • 900 pound gorilla of optimization • shove method/closure back to callsite • specialize closure-receiving methods • eliminate call protocol • We know Ruby better than the JVM
  • 42. JVM? • JVM will inline for us, but... • only if we use invokedynamic • and the code isn't too big • and it's not polymorphic • and we're not a closure (lambdas too!) • and it feels like it
  • 43. Today’s Inliner def decrement_one(i) i - 1 end i = 1_000_000 while i > 0 i = decrement_one(i) end def decrement_one(i) i - 1 end i = 1_000_000 while i < 0 if guard_same? self i = i - 1 else i = decrement_one(i) end end
  • 44. Today’s Inliner def decrement_one(i) i - 1 end i = 1_000_000 while i > 0 i = decrement_one(i) end def decrement_one(i) i - 1 end i = 1_000_000 while i < 0 if guard_same? self i = i - 1 else i = decrement_one(i) end end
  • 45. Today’s Inliner def decrement_one(i) i - 1 end i = 1_000_000 while i > 0 i = decrement_one(i) end def decrement_one(i) i - 1 end i = 1_000_000 while i < 0 if guard_same? self i = i - 1 else i = decrement_one(i) end end
  • 46. Today’s Inliner def decrement_one(i) i - 1 end i = 1_000_000 while i > 0 i = decrement_one(i) end def decrement_one(i) i - 1 end i = 1_000_000 while i < 0 if guard_same? self i = i - 1 else i = decrement_one(i) end end
  • 47. Profiling • You can't inline if you can't profile! • For each call site record call info • Which method(s) called • How frequently • Inline most frequently-called method
  • 48. Inlining a Closure def small_loop(i) k = 10 while k > 0 k = yield(k) end i - 1 end def big_loop(i) i = 100_000 while true i = small_loop(i) { |j| j - 1 } return 0 if i < 0 end end 900.times { |i| big_loop i } hot & monomorphic Like an Array#each May see many blocks JVM will not inline this
  • 50. Profiling • <2% overhead (to be reduced more) • Working* (interpreter AND JIT) • Feeds directly into inlining • Deopt coming soon * Fragile and buggy!
  • 51. Interpreter FTW! • Deopt is much simpler with interpreter • Collect local vars, instruction index • Raise exception to interpreter, keep going • Much cheaper than resuming bytecode
  • 52. Numeric Specialization • "Unboxing" • Ruby: everything's an object • Tagged pointer for Fixnum, Float • JVM: references OR primitives • Need to optimize numerics as primitive
  • 53. JVM? • Escape analysis is inadequate (today) • Hotspot will eliminate boxes if... • All code inlines • No (unfollowed?) branches in the code • Dynamic calls have type guards • Fixnum + Fixnum has overflow check
  • 54. def looper(n)
 i = 0
 while i < n
 do_something(i)
 i += 1
 end
 end def looper(long n)
 long i = 0
 while i < n
 do_something(i)
 i += 1
 end
 end Specialize n, i to long def looper(n)
 i = 0
 while i < n
 do_something(i)
 i += 1
 end
 end Deopt to object version if n or i + 1 is not Fixnum
  • 55. Unboxing Today • Working prototype • No deopt • No type guards • No overflow check for Fixnum/Bignum
  • 56. Rendering * * * * * *** ***** ***** *** * ********* ************* *************** ********************* ********************* ******************* ******************* ******************* ******************* *********************** ******************* ******************* ********************* ******************* ******************* ***************** *************** ************* ********* * *************** *********************** * ************************* * ***************************** * ******************************* * ********************************* *********************************** *************************************** *** ***************************************** *** ************************************************* *********************************************** ********************************************* ********************************************* *********************************************** *********************************************** *************************************************** ************************************************* ************************************************* *************************************************** *************************************************** * *************************************************** * ***** *************************************************** ***** ****** *************************************************** ****** ******* *************************************************** ******* *********************************************************************** ********* *************************************************** ********* ****** *************************************************** ****** ***** *************************************************** ***** *************************************************** *************************************************** *************************************************** *************************************************** ************************************************* ************************************************* *************************************************** *********************************************** *********************************************** ******************************************* ***************************************** ********************************************* **** ****************** ****************** **** *** **************** **************** *** * ************** ************** * *********** *********** ** ***** ***** ** * * * * 0.520000 0.020000 0.540000 ( 0.388744)
  • 57. def iterate(x,y)
 cr = y-0.5
 ci = x
 zi = 0.0
 zr = 0.0
 i = 0
 bailout = 16.0
 max_iterations = 1000
 
 while true
 i += 1
 temp = zr * zi
 zr2 = zr * zr
 zi2 = zi * zi
 zr = zr2 - zi2 + cr
 zi = temp + temp + ci
 return i if (zi2 + zr2 > bailout)
 return 0 if (i > max_iterations)
 end
 end
  • 58.
  • 59.
  • 62. Mandelbrot performance 0 0.035 0.07 0.105 0.14 JRuby + truffle JRuby on Graal JRuby unbox
  • 63. When? • Object shape should be in 9.1 • Profiling, inlining mostly need testing • Specialization needs guards, deopt • Active work over next 6-12mo
  • 64. Summary • JVM is great, but we need more • Partial EA, frame access, specialization • Gotta stay ahead of these youngsters! • JRuby 9000 is aVM on top of aVM • We believe we can match Truffle • (for a large range of optimizations)
  • 65. ThankYou • Charles Oliver Nutter • @headius • headius@headius.com