6. Ruby on JVM
• Core classes and runtime in Java
• Moving parts to Ruby over time
• Standard command line
• 1.8 and 1.9 compatible
• 1.9 default in JRuby 1.7
• Drop in replacement for MRI*
7. *caveats
• Weak but improving low-level UNIX stuff
• No C extension support
• Not maintained...off by default in 1.7
• Some features differ or unavailable
• ObjectSpace, trace funcs, callcc, fork...
8. JRuby 1.7
• Ruby 1.9.3 mode by default
• Many 1.9 compat fixes
• Numerous perf improvements
• Java 7 invokedynamic support
• Beginning of new optimizing compiler
9. Getting Started
• Need a JVM...
• rvm install jruby
• rvm install jruby-1.7.0-RC1
• Download manually
• Unpack, edit PATH, done
11. def fractal_flipflop
w, h = 44, 54
c = 7 + 42 * w
a = [0] * w * h
g = d = 0
f = proc do |n|
a[c] += 1
o = a.map {|z| " :#"[z, 1] * 2 }.join.scan(/.{#{w * 2}}/)
puts "f" + o.map {|l| l.rstrip }.join("n")
d += 1 - 2 * ((g ^= 1 << n) >> n)
c += [1, w, -1, -w][d %= 4]
end
1024.times do
!!(!!(!!(!!(!!(!!(!!(!!(!!(true...
f[0])...f[1])...f[2])...
f[3])...f[4])...f[5])...
f[6])...f[7])...f[8])
end
end
12. def fractal_flipflop
w, h = 44, 54
c = 7 + 42 * w
a = [0] * w * h
g = d = 0
f = proc do |n|
a[c] += 1
o = a.map {|z| " :#"[z, 1] * 2 }.join.scan(/.{#{w * 2}}/)
puts "f" + o.map {|l| l.rstrip }.join("n")
d += 1 - 2 * ((g ^= 1 << n) >> n)
c += [1, w, -1, -w][d %= 4]
end
1024.times do
!!(!!(!!(!!(!!(!!(!!(!!(!!(true...
f[0])...f[1])...f[2])...
f[3])...f[4])...f[5])...
f[6])...f[7])...f[8])
end
end
17. JRuby Team
Charlie Tom
Nick Hiro Marcin Nahi Wayne Subbu Douglas Douglas
Douglas
Contribs
18. JRuby Team
Charlie Tom
Nick Hiro Marcin Nahi Wayne Subbu Douglas Douglas
Douglas
Contribs
Douglas
Douglas Douglas
Douglas Douglas
Douglas Douglas
Other
Douglas
OpenJDK Android J9
JVMs
19. JRuby Structure
JRuby
Bytecode Core Java
Parser
JIT Classes Integ
JVM
Native
Threads GC C API
JIT
20. JRuby Structure
JRuby
Bytecode Core Java
Parser
JIT Classes Integ
JRuby team can focus on implementing JRuby.
21. JRuby Team Doesn’t
Have to Work On*
• Memory allocation • Native JIT
• Garbage collectors • Tooling
• Native threading • Server environments
• Cross-platform • Native extensions
• Mobile/Embedded VMs
22. We could stop working
on JRuby and it would
continue to get faster.
34. TorqueBox AS
Sinatra Rails
Rack Tasks Procs Jobs Daemons
Web Messaging Scheduling Services
JBoss AS
Clustering Load Balancing HA
35. Torquebox
• Rack-compatible • Server management
• Database connectivity • Clustering
• Background daemons • In and out-process cache
• Scheduled jobs • Web sockets
• Messaging • Authentication
• Asynchronous tasks • XA Transactions
36. Torquebox
• Rack-compatible • Server management
• Database connectivity • Clustering
• All R
Background daemons • In and out-process cache
• Scheduled jobs
uby • Web sockets
• Messaging
APIs
• Authentication
• Asynchronous tasks • ! XA Transactions
37. Ruby-friendly Config
TorqueBox.configure do
ruby do ruby:
version "1.9" version: 1.9
compile_mode "off" compile_mode: off
debug false debug: false
interactive true interactive: true
profile_api true profile_api: true
end
end
38. Messaging
application:
TorqueBox.configure do ..
... queues:
queue '/queues/my_app_queue' /queues/my_app_queue:
topic '/queues/my_app_topic'
end topics:
/queues/my_app_topic:
39. Messaging
queue = fetch('/queues/foo')
queue.publish "A text message"
topic = fetch('/topics/foo')
topic.publish "A text message"
queue = TorqueBox::Messaging::Queue.new('/queues/foo')
message = queue.receive
topic = TorqueBox::Messaging::Topic.new('/topics/foo')
message = topic.receive
47. turtle("four-sided triangle") do |*args|
dim = (args[0] || 5).to_i
block_type = (args[1] || :stone).to_sym
layer do
4.times do |i|
forward dim
turnleft 90
end
end
pivot do
block :none
forward 1
turnleft 90
forward 1
turnup 90
forward 1
turndown 90
turnright 90
block block_type
end
block block_type
(1...dim).step(2).to_a.reverse.each do |i|
dim = i
layer
pivot
end
end
48. Threepence
• Ruby APIs atop Ardor3D library
• Various games atop Ardor3D
• All-in-one clone from Github
• Linux, OS X, Windows, Solaris provided
49. require 'example_base'
class Box < ExampleBase
def initialize
super("Box Example")
end
def init_application
root.layout do
cull_state :back
skybox(:sky, 500, 500, 500, 'images/skybox/blue')
node(:spinning) do
behavior :rotating, Vector3(1, 1, 0.5), 50
box(:left_box, 1, 1, 1) do
behavior :rotating, Vector3(0.5, 1, 1), 50
at 0, 0, -3
texture "images/ardor3d_white_256.jpg"
end.duplicate_as(:right_box) do
at 0, 0, 3
" end
end
end
end
end
Box.start
55. class Simple
attr_accessor :next
end
top = Simple.new
puts Benchmark.measure {
outer = 10
total = 100000
per = 100
outer.times do
total.times do
per.times { Simple.new }
s = Simple.new
top.next = s
top = s
end
end
}
63. JRuby (Concurrent) Ruby 2.0.0
World-stopping GC pause times
0.3s
0.225s
Pause time
0.15s
0.075s
0s
0 5 10 15 20
Seconds since start
64. JRuby (Concurrent) Ruby 2.0.0
World-stopping GC pause times
0.3s
im es
0.225s
useT
Pa
Pause time
0.15s
0.075s
0s
0 5 10 15 20
Seconds since start
65. JRuby (Concurrent) Ruby 2.0.0
World-stopping GC pause times
0.3s
im es
0.225s
useT
Pa
Pause time
0.15s
Use
r Ha
ppi
0.075s nes
s :-
(
0s
0 5 10 15 20
Seconds since start
66. Findings
• Lower, more uniform individual GC time
• Lower overall GC time
• Lower application pause times
• More predictable, consistent apps
80. Monitoring
• Java Management Extensions (JMX)
• Gems available for clients and servers
• jconsole and VisualVM
• Most servers provide additional tools
• New Relic, etc have JVM support
81. VisualVM
• CPU, memory, thread monitoring
• CPU and memory profiling
• VisualGC
• Heap analysis
85. Performance
• JRuby compiles Ruby to JVM bytecode
• JVM compiles bytecode to native
• Best JIT technology in the world
• Getting even better with invokedynamic
86. def foo
bar
end
def bar
baz foo bar baz
end
def baz
# ...
end
87. JRuby on Java 5/6
def foo
bar
end
def bar JRuby JRuby
baz foo call bar call baz
end logic logic
def baz
# ...
end
Kills many JVM optimizations
88. JRuby on Java 7
def foo
bar
X X
end
def bar JRuby JRuby
baz foo call bar call baz
end logic logic
def baz
# ...
end
Dynamic call logic built into JVM
89. JRuby on Java 7
def foo
bar
end
def bar
baz foo bar baz
end
def baz
# ...
end
Straight through dispatch path
90. JRuby on Java 7
def foo
bar
end
def bar
baz foo bar baz
end
def baz
# ...
end
Optimizations (like inlining) can happen!
91. def foo; 1; end
def invoker; foo; end
i = 0
while i < 10000
invoker
i+=1
end
0x00000001060a1be0: mov %eax,-0x14000(%rsp)
0x00000001060a1be7: push %rbp
0x00000001060a1be8: sub $0x30,%rsp
0x00000001060a1bec: mov 0x8(%rcx),%r10d
0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d
0x00000001060a1bf7: jne 0x00000001060a1c39
0x00000001060a1bf9: mov %rcx,%r10
0x00000001060a1bfc: mov 0x10(%r10),%ebp
0x00000001060a1c00: cmp $0xfed77602,%ebp
0x00000001060a1c06: jne 0x00000001060a1c1e
0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax
0x00000001060a1c12: add $0x30,%rsp
0x00000001060a1c16: pop %rbp
0x00000001060a1c17: test %eax,-0xec3c1d(%rip)
0x00000001060a1c1d: retq
92. def invoker; 1; end
i = 0
while i < 10000
invoker
i+=1
end
0x00000001060a1be0: mov %eax,-0x14000(%rsp)
0x00000001060a1be7: push %rbp
0x00000001060a1be8: sub $0x30,%rsp
0x00000001060a1bec: mov 0x8(%rcx),%r10d
0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d
0x00000001060a1bf7: jne 0x00000001060a1c39
0x00000001060a1bf9: mov %rcx,%r10
0x00000001060a1bfc: mov 0x10(%r10),%ebp
0x00000001060a1c00: cmp $0xfed77602,%ebp
0x00000001060a1c06: jne 0x00000001060a1c1e
0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax
0x00000001060a1c12: add $0x30,%rsp
0x00000001060a1c16: pop %rbp
0x00000001060a1c17: test %eax,-0xec3c1d(%rip)
0x00000001060a1c1d: retq
93. i = 0
while i < 10000
1
i+=1
end
0x00000001060a1be0: mov %eax,-0x14000(%rsp)
0x00000001060a1be7: push %rbp
0x00000001060a1be8: sub $0x30,%rsp
0x00000001060a1bec: mov 0x8(%rcx),%r10d
0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d
0x00000001060a1bf7: jne 0x00000001060a1c39
0x00000001060a1bf9: mov %rcx,%r10
0x00000001060a1bfc: mov 0x10(%r10),%ebp
0x00000001060a1c00: cmp $0xfed77602,%ebp
0x00000001060a1c06: jne 0x00000001060a1c1e
0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax
0x00000001060a1c12: add $0x30,%rsp
0x00000001060a1c16: pop %rbp
0x00000001060a1c17: test %eax,-0xec3c1d(%rip)
0x00000001060a1c1d: retq
94. i = 0
while i < 10000
i+=1
end
0x00000001060a1be0: mov %eax,-0x14000(%rsp)
0x00000001060a1be7: push %rbp
0x00000001060a1be8: sub $0x30,%rsp
0x00000001060a1bec: mov 0x8(%rcx),%r10d
0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d
0x00000001060a1bf7: jne 0x00000001060a1c39
0x00000001060a1bf9: mov %rcx,%r10
0x00000001060a1bfc: mov 0x10(%r10),%ebp
0x00000001060a1c00: cmp $0xfed77602,%ebp
0x00000001060a1c06: jne 0x00000001060a1c1e
0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax
0x00000001060a1c12: add $0x30,%rsp
0x00000001060a1c16: pop %rbp
0x00000001060a1c17: test %eax,-0xec3c1d(%rip)
0x00000001060a1c1d: retq
95. 0x00000001060a1be0: mov %eax,-0x14000(%rsp)
0x00000001060a1be7: push %rbp
0x00000001060a1be8: sub $0x30,%rsp
0x00000001060a1bec: mov 0x8(%rcx),%r10d
0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d
0x00000001060a1bf7: jne 0x00000001060a1c39
0x00000001060a1bf9: mov %rcx,%r10
0x00000001060a1bfc: mov 0x10(%r10),%ebp
0x00000001060a1c00: cmp $0xfed77602,%ebp
0x00000001060a1c06: jne 0x00000001060a1c1e
0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax
0x00000001060a1c12: add $0x30,%rsp
0x00000001060a1c16: pop %rbp
0x00000001060a1c17: test %eax,-0xec3c1d(%rip)
0x00000001060a1c1d: retq
101. smooth_sort
# Original Author: Keith Schwarz (htiek@cs.stanford.edu)
#
# Translated to Ruby by Chuck Remes (chuckremes on github)
#
# An implementation of Dijkstra's Smoothsort algorithm, a modification of
# heapsort that runs in O(n lg n) in the worst case, but O(n) if the data
# are already sorted. For more information about how this algorithm works
# and some of the details necessary for its proper operation, please see
#
# http://www.keithschwarz.com/smoothsort/
107. Your Turn
• Try your apps on JRuby and tell us
• Turn on JRuby in @travisci
• Let us know what you think of JRuby
• Help us make JRuby even better!