SlideShare a Scribd company logo
1 of 126
Why JRuby?
Who?




  Thomas      Charlie
@tom_enebo   @headius
What is JRuby?
JRuby is Ruby! *
   1.8.7 & 1.9.3 compatibility
   drop-in replacement

                         * see next slide
*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...
JRuby is Ruby
     ...and then some?
Announcing JRuby 1.7.0

• Ruby 1.9.3 compat (--1.8 for 1.8.7)
• Java 7 invokedynamic support
• Much awesomeness over 1.6.x
Getting Started

1. Install a JVM
2. rvm install jruby
3. Profit!
        % jruby -e ‘puts “wowee”’
The JRuby Difference
JRuby Team

                  Charlie                       Tom




Nick   Hiro   Marcin        Nahi    Wayne      Subbu   Douglas   Douglas
                                                                  Douglas
                                                                  Contribs




                Douglas
                 Douglas       Douglas
                                Douglas     Douglas
                                              Other
                                             Douglas
                 OpenJDK         Android
                                               JVMs
JRuby

                JRuby
Yoko




          JVM
J. Rose



           OS (libc, ...)
MRI

nobu
           MRI




       OS (libc, ...)
JRuby

                JRuby
Yoko




          JVM
J. Rose



           OS (libc, ...)
We get it for Free!

               JVM
J. Rose



  Garbage                     Profiled
               Native JIT   Optimizations
 Collection

  Native        Tooling     Cross Platform
 Threading
Profile: John Rose
    • JVM Engineer since 1997
    • Invented C* Language
    • JSR 292 lead
JVM over time
(what if we were lazy?)
Go Java Go!                       300% for free
             JRuby 1.0.3 (bm_red_black_tree.rb)

 30



22.5



 15



 7.5



   0
  Java 1.4     Java 5                 Java 6             Java 7
Go Java Go!                          300% for free
             JRuby 1.0.3 (bm_red_black_tree.rb)                MRI 1.8

 30



22.5



 15



 7.5



   0
  Java 1.4               Java 5                   Java 6                 Java 7
JVM Benefits
Cross-Platform
JVM is everywhere

• Unix++, Windows
• Exotic platforms: zLinux, OpenVMS, AS/400
• Mobile: Android’s Dalvik, Embedded JVMs
Java bytecode ==
    portability
actionmailer-javamail, active_documentum, activerecord-jdbc-adapter, activerecord-jdbcdbf-adapter, activerecord-jdbcderby-adapter, activerecord-jdbch2-
adapter, activerecord-jdbchsqldb-adapter, activerecord-jdbcmssql-adapter, activerecord-jdbcmysql-adapter, activerecord-jdbcpostgresql-adapter, activerecord-
    jdbcsqlite3-adapter, activerecord-netezza-adapter, activerecord-vertica-adapter, akephalos, akephalos-nerian, akephalos2, akka-actor-jars, akka-remote-jars,
    akubra_llstore_migrate, Antwrap, async-http-client-jars, atomic, atoulme-Antwrap, autotest-java, bbrowning-deltacloud-client, bbrowning-deltacloud-core,
   bcrypt-ruby, bee_java, berkeley-db-java-jars, bert, bio-maf, blockenspiel, boc, bond, bosdk, bouncy-castle-java, boxed-geminabox, brute-fuzzy, bryanl-gherkin,
 bson, buby, buildr, buildr-resolver, buildrizpack, butternut, capistrano-java, capybara-java_script_lint, carrierwave-neo4j, carrierwave_imagevoodoo, cassandra-
   jars, chrest, cloby, commons-io-jars, concurrently, contextual, coupler, cucumber-java, cucumber-jvm, cuke4duke, cuuid, dm-ldap-adapter, dm-lucene-adapter,
  do-jdbc_sqlserver, do_derby, do_h2, do_hsqldb, do_jdbc, do_mysql, do_openedge, do_oracle, do_postgres, do_sqlite3, do_sqlserver, doubleshot, dripdrop,
    dubious, duby, engineyard-visualvm, epall-limelight, errbit_zmq_handler, eurydice, euston, euston-daemons, euston-eventstore, euston-projections, euston-
   rabbitmq, euston-websites, eventmachine, excemel, faye-websocket, ffi, fig, file-find, fishwife, foreman, forkit, forkjoin, gamelan, gemshit, geoip-jars, get_back,
 gherkin, glassfish, gravitext-util, gravitext-xmlprod, grizzly, guava-jars, hadoop-find, hashdot-test-daemon, hiredis, hitimes, hope, hostor, hot_bunnies, hourglass,
 hpricot, http_parser.rb, inline_javascript, iudex, iudex-async-httpclient, iudex-barc, iudex-brutefuzzy-protobuf, iudex-brutefuzzy-service, iudex-char-detector,
 iudex-core, iudex-da, iudex-filter, iudex-html, iudex-http, iudex-http-test, iudex-httpclient-3, iudex-jetty-httpclient, iudex-rome, iudex-simhash, iudex-worker,
            ivy-jars, iyyov, jactive_support, java-autotest, java-inline, java2ruby-xmldsig, java_bin, java_inline, java_override, java_properties, java_streamify,
java_testing_guff, javabean_xml, javaclass, javaeye4r, javagems, javajake, javaobj, javaobjs, javaobs, javaparse, javasand, javascript-securehash-rails, javascript-state-
                machine-rails, javascript_auto_include, javascript_eraser, javascript_features, javascript_i18n, javascript_localize, javascript_safe_logger,
  javascript_util_asset_pack, javascripto, javascripto-rails, jdbc-derby, jdbc-hsqldb, jdbc-jtds, jdbc-openedge, jdbc-openedge-internal, jdbc-postgres, jdbc-sqlite3,
      jedis-jars, jena-jruby, jessica, jettr, jetty, jetty-jsp, jgeoip, jms4r, jpdfer, jrack_handlers, jrtm, jruby-activemq, jruby-akka_jars, jruby-elasticsearch_jars, jruby-
      httpclient, jruby-launcher, jruby-management, jruby-metrics, jruby-pageant, jruby-vijava, jruby_gc_stats, jruby_sandbox, jruby_threach, jrubyconf-button,
  jsmetric4java, json, json-jruby, jsound, kb-activerecord-jdbc-adapter, kirk, kyotocabinet-java, ladle, latex-decode, launchy, libnotify, limelight, linecache, logback,
       logback-jars, looksee, lumix, mack-javascript, markdownj, maven_irb_plugin, metrics-core-jars, metrics-java, mguymon-buildr, mikka, mini_aether, mirah,
mirah_model, miso-java, mixology, mm_mq, mongrel, msgpack-idl-java, msgpack-jruby, multimeter, naether, nanoc-javascript-concatenator, neo4j, neo4j-admin,
      neo4j-advanced, neo4j-community, neo4j-core, neo4j-enterprise, neo4j-spatial, neo4j-will_paginate, neo4j-wrapper, netty-jars, ning-compress-jars, nio4r,
nokogiri, nokogiri-fitzsimmons, nokogiri-maven, nosqoop4u, ontomde-demo-java5, ontomde-java, ontomde-java-frontend, ontomde-uml2-java, ontomde-uml2-
               kbjava, open_nlp, pacer, pacer-dex, pacer-neo4j, pacer-orient, pelops-jars, persvr, pg_array_parser, protobuf-jars, pry, puma, qtjruby-core,
      qwirk_active_mq_adapter, qwirk_jms_adapter, rabbitmqadmin-cli, ragweed, rails_javascript_helpers, rakejava, rave, rcov, realityforge-jekyll, realityforge-
    jekylltask, redcar-bundles, redcar-clojure, redcar-filter-through-command, redcar-groovy, redcar-icons, redcar-javamateview, redcar-javascript, redcar-mirah,
        redcar-svnkit, redcar-xulrunner-win, RedCloth, refinerycms-javascripts, reigns, revo-nokogiri, rika, rjack-async-httpclient, rjack-commons-codec, rjack-
commons-dbcp, rjack-commons-dbutils, rjack-commons-pool, rjack-httpclient-3, rjack-httpclient-4, rjack-icu, rjack-jackson, rjack-jdom, rjack-jets3t, rjack-jetty,
     rjack-jetty-jsp, rjack-jms, rjack-jms-spec, rjack-logback, rjack-lucene, rjack-maven, rjack-mina, rjack-nekohtml, rjack-protobuf, rjack-qpid-client, rjack-rome,
  rjack-slf4j, rjack-solr, rjack-tarpit, rjack-xerces, rmagick4j, rmodbus, rtm-javatmapi, rtm-majortom, rtm-ontopia, rtm-tinytim, rtm-tmql, rubeus, rubinius-core-
 api, ruby-blockcache, ruby-debug-base, ruby-maven, ruby2java, rubydoop, rubyjedi-nokogiri_java, scala-inline, scala-library-jars, scriptty, slf4j, slf4j-jars, slyphon-
     zookeeper, slyphon-zookeeper_jar, smackr, smartimage, SNMP4JR, solr_sail, spiegela-jruby-httpclient, sproutcore, spymemcached, sqldroid, steamcannon-
 deltacloud-client, steamcannon-deltacloud-core, stilts-stomp-client, supermarket, svm_toolkit, swt, theduke, thick, to-javascript, torquebox-base, torquebox-
    cache, torquebox-configure, torquebox-container-foundation, torquebox-core, torquebox-messaging, torquebox-messaging-container, torquebox-naming,
 torquebox-naming-container, torquebox-security, torquebox-server, torquebox-vfs, torquebox-web, twitter4j4r, UDJrb, unageanu-javaclass, unimidi, universe-
 javascript, url_escape, weakling, webbit-jars, wildnet-jackson, wildnet-netty, wildnet-server, wildsonet-hazelcast, wildsonet-netty, wildsonet-server, wildsonet-
                                                                   streamer, wrest, wrong, xdojava, xqruby, zookeeper
actionmailer-javamail, active_documentum, activerecord-jdbc-adapter, activerecord-jdbcdbf-adapter, activerecord-jdbcderby-adapter, activerecord-jdbch2-
adapter, activerecord-jdbchsqldb-adapter, activerecord-jdbcmssql-adapter, activerecord-jdbcmysql-adapter, activerecord-jdbcpostgresql-adapter, activerecord-
    jdbcsqlite3-adapter, activerecord-netezza-adapter, activerecord-vertica-adapter, akephalos, akephalos-nerian, akephalos2, akka-actor-jars, akka-remote-jars,
    akubra_llstore_migrate, Antwrap, async-http-client-jars, atomic, atoulme-Antwrap, autotest-java, bbrowning-deltacloud-client, bbrowning-deltacloud-core,
   bcrypt-ruby, bee_java, berkeley-db-java-jars, bert, bio-maf, blockenspiel, boc, bond, bosdk, bouncy-castle-java, boxed-geminabox, brute-fuzzy, bryanl-gherkin,
 bson, buby, buildr, buildr-resolver, buildrizpack, butternut, capistrano-java, capybara-java_script_lint, carrierwave-neo4j, carrierwave_imagevoodoo, cassandra-
   jars, chrest, cloby, commons-io-jars, concurrently, contextual, coupler, cucumber-java, cucumber-jvm, cuke4duke, cuuid, dm-ldap-adapter, dm-lucene-adapter,
  do-jdbc_sqlserver, do_derby, do_h2, do_hsqldb, do_jdbc, do_mysql, do_openedge, do_oracle, do_postgres, do_sqlite3, do_sqlserver, doubleshot, dripdrop,
    dubious, duby, engineyard-visualvm, epall-limelight, errbit_zmq_handler, eurydice, euston, euston-daemons, euston-eventstore, euston-projections, euston-
   rabbitmq, euston-websites, eventmachine, excemel, faye-websocket, ffi, fig, file-find, fishwife, foreman, forkit, forkjoin, gamelan, gemshit, geoip-jars, get_back,
 gherkin, glassfish, gravitext-util, gravitext-xmlprod, grizzly, guava-jars, hadoop-find, hashdot-test-daemon, hiredis, hitimes, hope, hostor, hot_bunnies, hourglass,
 hpricot, http_parser.rb, inline_javascript, iudex, iudex-async-httpclient, iudex-barc, iudex-brutefuzzy-protobuf, iudex-brutefuzzy-service, iudex-char-detector,
 iudex-core, iudex-da, iudex-filter, iudex-html, iudex-http, iudex-http-test, iudex-httpclient-3, iudex-jetty-httpclient, iudex-rome, iudex-simhash, iudex-worker,
            ivy-jars, iyyov, jactive_support, java-autotest, java-inline, java2ruby-xmldsig, java_bin, java_inline, java_override, java_properties, java_streamify,
java_testing_guff, javabean_xml, javaclass, javaeye4r, javagems, javajake, javaobj, javaobjs, javaobs, javaparse, javasand, javascript-securehash-rails, javascript-state-
                machine-rails, javascript_auto_include, javascript_eraser, javascript_features, javascript_i18n, javascript_localize, javascript_safe_logger,
  javascript_util_asset_pack, javascripto, javascripto-rails, jdbc-derby, jdbc-hsqldb, jdbc-jtds, jdbc-openedge, jdbc-openedge-internal, jdbc-postgres, jdbc-sqlite3,



                                                No build tools!
      jedis-jars, jena-jruby, jessica, jettr, jetty, jetty-jsp, jgeoip, jms4r, jpdfer, jrack_handlers, jrtm, jruby-activemq, jruby-akka_jars, jruby-elasticsearch_jars, jruby-
      httpclient, jruby-launcher, jruby-management, jruby-metrics, jruby-pageant, jruby-vijava, jruby_gc_stats, jruby_sandbox, jruby_threach, jrubyconf-button,
  jsmetric4java, json, json-jruby, jsound, kb-activerecord-jdbc-adapter, kirk, kyotocabinet-java, ladle, latex-decode, launchy, libnotify, limelight, linecache, logback,
       logback-jars, looksee, lumix, mack-javascript, markdownj, maven_irb_plugin, metrics-core-jars, metrics-java, mguymon-buildr, mikka, mini_aether, mirah,
mirah_model, miso-java, mixology, mm_mq, mongrel, msgpack-idl-java, msgpack-jruby, multimeter, naether, nanoc-javascript-concatenator, neo4j, neo4j-admin,
      neo4j-advanced, neo4j-community, neo4j-core, neo4j-enterprise, neo4j-spatial, neo4j-will_paginate, neo4j-wrapper, netty-jars, ning-compress-jars, nio4r,
nokogiri, nokogiri-fitzsimmons, nokogiri-maven, nosqoop4u, ontomde-demo-java5, ontomde-java, ontomde-java-frontend, ontomde-uml2-java, ontomde-uml2-
               kbjava, open_nlp, pacer, pacer-dex, pacer-neo4j, pacer-orient, pelops-jars, persvr, pg_array_parser, protobuf-jars, pry, puma, qtjruby-core,
      qwirk_active_mq_adapter, qwirk_jms_adapter, rabbitmqadmin-cli, ragweed, rails_javascript_helpers, rakejava, rave, rcov, realityforge-jekyll, realityforge-
    jekylltask, redcar-bundles, redcar-clojure, redcar-filter-through-command, redcar-groovy, redcar-icons, redcar-javamateview, redcar-javascript, redcar-mirah,
        redcar-svnkit, redcar-xulrunner-win, RedCloth, refinerycms-javascripts, reigns, revo-nokogiri, rika, rjack-async-httpclient, rjack-commons-codec, rjack-
commons-dbcp, rjack-commons-dbutils, rjack-commons-pool, rjack-httpclient-3, rjack-httpclient-4, rjack-icu, rjack-jackson, rjack-jdom, rjack-jets3t, rjack-jetty,
     rjack-jetty-jsp, rjack-jms, rjack-jms-spec, rjack-logback, rjack-lucene, rjack-maven, rjack-mina, rjack-nekohtml, rjack-protobuf, rjack-qpid-client, rjack-rome,
  rjack-slf4j, rjack-solr, rjack-tarpit, rjack-xerces, rmagick4j, rmodbus, rtm-javatmapi, rtm-majortom, rtm-ontopia, rtm-tinytim, rtm-tmql, rubeus, rubinius-core-
 api, ruby-blockcache, ruby-debug-base, ruby-maven, ruby2java, rubydoop, rubyjedi-nokogiri_java, scala-inline, scala-library-jars, scriptty, slf4j, slf4j-jars, slyphon-
     zookeeper, slyphon-zookeeper_jar, smackr, smartimage, SNMP4JR, solr_sail, spiegela-jruby-httpclient, sproutcore, spymemcached, sqldroid, steamcannon-
 deltacloud-client, steamcannon-deltacloud-core, stilts-stomp-client, supermarket, svm_toolkit, swt, theduke, thick, to-javascript, torquebox-base, torquebox-
    cache, torquebox-configure, torquebox-container-foundation, torquebox-core, torquebox-messaging, torquebox-messaging-container, torquebox-naming,
 torquebox-naming-container, torquebox-security, torquebox-server, torquebox-vfs, torquebox-web, twitter4j4r, UDJrb, unageanu-javaclass, unimidi, universe-
 javascript, url_escape, weakling, webbit-jars, wildnet-jackson, wildnet-netty, wildnet-server, wildsonet-hazelcast, wildsonet-netty, wildsonet-server, wildsonet-
                                                                   streamer, wrest, wrong, xdojava, xqruby, zookeeper
Libraries
 Lucene     Neo4j
                         Selenium

47k libraries in Maven
Hadoop         EHCache

    JMonkeyEngine
                           Sitemesh
Languages/Polyglot
      Clojure                 Scala

                     Jython


Rhino/Nashorn/                Groovy
DynJS (JavaScript)
             Micro Focus JVM Visual COBOL
Polyglot

• Use right tool for the right job
• Running in the same VM
• Another dimension of libraries
GC
GC Matters

• Applications grow over time
• Ruby is very object-heavy
• Multiprocess multiplies the problem
• You will eventually have issues
JVM GC

• Wide array of options
• Many GCs to choose from
• Scales up to massive heaps
• Best GCs in the world!
OpenJDK GCs

• Parallel: multi-core stop-the-world
• Concurrent: STW young, concurrent old
• G1: concurrent young and old
• Serial: single-thread STW
Object Homogeneity

• Everything expressed as JVM objects
• Everything shares the same infrastructure
 • Including extensions, libraries, etc
• One GC to rule them all
 • And one standard memory model
gc_demo.rb


• Heavy GC, mix of old and young
• Steadily growing heap use
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
}
Ruby 1.9.3              JRuby
8000



6000



4000



2000



   0
                    GC count
Ruby 1.9.3              JRuby
10000



 1000



  100



   10



    1
                     GC count
15
        Ruby 1.9.3               JRuby



11.25




  7.5




 3.75




   0
                     GC time %
Ruby 2.0.0                      JRuby
                               Time per GC versus heap usage
              300ms



              225ms
Time per GC




              150ms



              75ms



               0ms
               188KB/29MB                  27MB/127MB               199MB/238MB
                                   Heap usage (MRI/JRuby)
Ruby 2.0.0                      JRuby
                                   Time per GC versus heap usage

                   :-(

                   :-(
User Unhappiness




                   :-/

                   :-|

                   :-)
                   188KB/29MB                  27MB/127MB               199MB/238MB
                                       Heap usage (MRI/JRuby)
Ruby 2.0.0

                   4,000




                   3,000
Time Per GC (ms)




                   2,000




                   1,000




                      0
                           0M   1,250M       2,500M     3,750M   5,000M
                                            Heap Size
Findings

• Lower, more uniform GC times
• Reduced or eliminated pauses
• Very large heaps are no problem
• Predictable, consistent experience
Threads
Real Parallellism

• Ruby thread = JVM thread = native thread
• One process can use all cores
• One server can handle all requests
require 'benchmark'

ary = (1..1000000).to_a

loop {
  puts Benchmark.measure {
    10.times {
      ary.each {|i|}
    }
  }
}
require 'benchmark'

ary = (1..1000000).to_a

loop {
  puts Benchmark.measure {
    (1..10).map {
      Thread.new {
        ary.each {|i|}
      }
    }.map(&:join)
  }
}
Ruby 1.9
unthreaded
Ruby 1.9    Ruby 1.9
unthreaded   threaded
Ruby 1.9    Ruby 1.9
unthreaded   threaded




  JRuby
unthreaded
Ruby 1.9    Ruby 1.9
unthreaded   threaded




  JRuby        JRuby
unthreaded   threaded
threaded_reverse
                     Per-iteration time versus thread count
 0.8s



0.65s



 0.5s



0.35s



 0.2s
        one thread      two threads        three threads      four threads
Nonlinear?

• More work means more objects
• Allocation/GC needs memory bandwidth
• No different from multi-process
Tools
Profiling

• Java profilers
 • VisualVM,YourKit, NetBeans, JXInsight
• jruby [--profile | --profile.graph]
• jruby -Xreify.classes=true
• JVM command-line profilers
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
VisualVM

• CPU, memory, thread monitoring
• CPU and memory profiling
• VisualGC
• Heap analysis
JRuby Goodies
Scripting Java
JavaFX straight port



      Simple Clock
@minute_hand = Path.new.tap do |mh|       Draw minute hand
  mh.setFill(Color::BLACK)
  mh.getElements.add MoveTo.new(4, -4)
  mh.getElements.add ArcTo.new(-1, -1, 0, -4, -4, false, false)
  mh.getElements.add LineTo.new(0, -radius)
  mh.getTransforms.add Rotate.new
end
                                        Implement Java Event
class Refresher
  include EventHandler                        handler
  def handle(event); event.source.refresh; end
end
                                       refresh timeline every 1s
Timeline.new.tap do |time|
  time.setCycleCount Timeline::INDEFINITE
  time.getKeyFrames.add(Keyframe.new(Duration.millis(1000)),
                        Refresher.new)
  time.play
end
getFooBar -> fooBar
@minute_hand = Path.new.tap do |mh|
  mh.setFill(Color::BLACK)          was getElements
  mh.elements.add MoveTo.new(4, -4)
  mh.elements.add ArcTo.new(-1, -1, 0, -4, -4, false, false)
  mh.elements.add LineTo.new(0, -radius)
  mh.transforms.add Rotate.new
end                            was getTransforms
class Refresher
  include EventHandler
  def handle(event); event.source.refresh; end
end

Timeline.new.tap do |time|
  time.setCycleCount Timeline::INDEFINITE
  time.keyFrames.add(Keyframe.new(Duration.millis(1000)),
                     Refresher.new)
  time.play
end                  was getKeyFrames
setFoo(a) -> foo = a
@minute_hand = Path.new.tap do |mh|
  mh.fill = Color::BLACK            was setFill
  mh.elements.add MoveTo.new(4, -4)
  mh.elements.add ArcTo.new(-1, -1, 0, -4, -4, false, false)
  mh.elements.add LineTo.new(0, -radius)
  mh.transforms.add Rotate.new
end

class Refresher
  include EventHandler
  def handle(event); event.source.refresh; end
end

Timeline.new.tap do |time|
                                was setCycleCount
  time.cycleCount = Timeline::INDEFINITE
  time.keyFrames.add(Keyframe.new(Duration.millis(1000)),
                     Refresher.new)
  time.play
end
camelCase -> camel_case
@minute_hand = Path.new.tap do |mh|
  mh.fill = Color::BLACK
  mh.elements.add MoveTo.new(4, -4)
  mh.elements.add ArcTo.new(-1, -1, 0, -4, -4, false, false)
  mh.elements.add LineTo.new(0, -radius)
  mh.transforms.add Rotate.new
end

class Refresher
  include EventHandler
  def handle(event); event.source.refresh; end
end

Timeline.new.tap do |time|             was cycleCount
  time.cycle_count = Timeline::INDEFINITE
  time.key_frames.add(Keyframe.new(Duration.millis(1000)),
                      Refresher.new)
  time.play
end                                  was keyFrames
Procs as interfaces
@minute_hand = Path.new.tap do |mh|
  mh.fill = Color::BLACK
  mh.elements.add MoveTo.new(4, -4)
  mh.elements.add ArcTo.new(-1, -1, 0, -4, -4, false, false)
  mh.elements.add LineTo.new(0, -radius)
  mh.transforms.add Rotate.new
end                                   No more extra class
Timeline.new.tap do |time|
  time.cycle_count = Timeline::INDEFINITE
  time.key_frames.add Keyframe.new(Duration.millis(1000)) {refresh}
  time.play
end
Common Adornments
                     ‘add’ becomes ‘<<‘
@minute_hand = Path.new.tap do   |mh|
  mh.fill = Color::BLACK
  mh.elements << MoveTo.new(4,   -4)
  mh.elements << ArcTo.new(-1,   -1, 0, -4, -4, false, false)
  mh.elements << LineTo.new(0,   -radius)
  mh.transforms << Rotate.new
end

Timeline.new.tap do |time|
  time.cycle_count = Timeline::INDEFINITE
  time.key_frames << Keyframe.new(Duration.millis(1000)) {refresh}
  time.play
end
Purugin

• Minecraft scripting in JRuby
• Clean and simple DSL
• Purogo: LOGO for Minecraft
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
Pimping a side-project


https://github.com/enebo/Purugin
Java Native Extensions
Native Extensions Suck
“Look, nobody enjoys
shooting penguins, but if
you have to shoot penguins,
well, you might as well
enjoy it.”
           - Free Waterfall Sr.
Flowchart of Shame
Can I write it in Ruby?               Script Java?
                               no
            yes                             no

    Does it need                     Can I use FFI?
    to be n times
       faster?                              no
                          no
                                    Native Extension
Java Native Extensions

• Written in Java
 • Have same performance as Java
 • Use same GC as JRuby
 • First Class Citizens
Performance
Go Java Go!                       300% for free
             JRuby 1.0.3 (bm_red_black_tree.rb)

 30



22.5



 15



 7.5



   0
  Java 1.4     Java 5                 Java 6             Java 7
Go JRuby Go!
                 OpenJDK 8 (bm_red_black_tree.rb)

8



6



4



2



0
 1.0.3   1.1.6          1.4.0       1.5.6           1.6.8   1.7.0
Severe gains???
                   OpenJDK 8 (bm_red_black_tree.rb)

  9
            Severe perf bottleneck(s)
6.75



 4.5



2.25



  0
   1.0.3   1.1.6          1.4.0       1.5.6           1.6.8   1.7.0
1.0.3 & red_black_tree
       -J-verbose:gc
          [GC (Allocation Failure) 223608K->96408K(330752K), 0.0159780 secs]
         [GC (Allocation Failure) 208920K->100792K(335168K), 0.0157550 secs]
         [GC (Allocation Failure) 213304K->105144K(332160K), 0.0181010 secs]
8.1s     [GC (Allocation Failure) 205112K->108920K(334400K), 0.0187580 secs]
         [GC (Allocation Failure) 208888K->112712K(329152K), 0.0154440 secs]
                                       +28 more


         [GC (Allocation Failure) 313780K->199892K(339072K), 0.0142010 secs]
         [GC (Allocation Failure) 318420K->204420K(331520K), 0.0175690 secs]
8.4s     [GC (Allocation Failure) 306948K->208316K(335680K), 0.0188120 secs]
           [Full GC (Ergonomics) 208316K->54991K(352256K), 0.2709750 secs]
          [GC (Allocation Failure) 157519K->58959K(349248K), 0.0120840 secs]
                                       +28 more



                              Moar Objects!
1.7.0 & red_black_tree
-J-verbose:gc
  [GC (Allocation Failure) 155729K->39697K(207296K), 0.0072730 secs]
                             0.963s
  [GC (Allocation Failure) 160785K->40657K(208320K), 0.0108620 secs]
                             0.968s
  [GC (Allocation Failure) 161745K->41649K(210112K), 0.0083760 secs]
                             0.968s
  [GC (Allocation Failure) 166193K->39729K(210688K), 0.0070670 secs]
                              0.99s
OpenJDK 8 (bm_red_black_tree.rb)

  3



2.25



 1.5



0.75



  0
   1.1.6   1.4.0          1.5.6          1.6.8   1.7.0
OpenJDK 8 (bm_red_black_tree.rb)

  3

                                      JVM Feature!
2.25



 1.5



0.75



  0
   1.1.6   1.4.0          1.5.6          1.6.8       1.7.0
Performance

• JRuby compiles Ruby to JVM bytecode
• JVM compiles bytecode to native
• Best JIT technology in the world
• Getting even better with invokedynamic
How to Optimize Ruby
• Do less work
 • Reduce dispatch and call overhead
 • Reduce memory overhead
• Find static patterns
 • Profile running code
 • Emit optimized version with guards
JVM Optimizations
• Profiling
 • Watch code, optimize hottest paths
• Inlining
 • Combine code, optimize as a whole
• Escape analysis
 • Eliminate transient objects
def foo; Object.new; end
def invoker; foo; end
i = 0
while i < 10000
  invoker
  i+=1
end
Inline foo into invoker
  def invoker; Object.new; end
  i = 0
  while i < 10000
    invoker
    i+=1
  end
Inline invoker into loop

  i = 0
  while i < 10000
    Object.new
    i+=1
  end
Object is transient

i = 0
while i < 10000

  i+=1
end
Loop does nothing

i = 10000
Variable i is never read
InvokeDynamic

• Java 7+ feature
• Allows us to teach JVM about Ruby
 • Dynamic calls can inline
 • Constants become truly constant
 • JVM’s best optimizations can work
Does It Work?
def foo; 1; end
def invoker; foo; end
N.times do
  i = 0
  while i < 10000
   invoker
   i+=1
  end
end
$ jruby -J-XX:+UnlockDiagnosticVMOptions 
         -J-XX:+PrintInlining 
         -J-XX:+PrintCompilation 
         script.rb
      79    1    b        java.lang.String::hashCode (55 bytes)
     109    2    b        java.util.Properties$LineReader::readLine (452 bytes)
                   @ 48  java.io.Reader::read (9 bytes)   never executed
                   @ 62  java.io.FilterInputStream::read (9 bytes)
                   @ 303  java.lang.System::arraycopy (0 bytes)    (intrinsic)
                   @ 388  java.io.Reader::read (9 bytes)   never executed
....
def foo; 1; end
                   def invoker; foo; end
                   N.times do
                     i = 0
                     while i < 10000
                      invoker
                      i+=1
                     end
                   end


3321 190     b        ruby.__dash_e__::block_0$RUBY$__file__ (83 bytes)
  @ 6   org.jruby.RubyFixnum::op_lt (22 bytes)   inline (hot)
  @ 66   org.jruby.RubyBasicObject::isTrue (15 bytes)    inline (hot)
  @ 6   ruby.__dash_e__::method__1$RUBY$invoker (9 bytes)    inline (hot)
    @ 6   ruby.__dash_e__::method__0$RUBY$foo (7 bytes)    inline (hot)
  @ 5   org.jruby.RubyFixnum::op_plus_one (31 bytes)    inline (hot)
def foo; 1; end
                   def invoker; foo; end
                   N.times do
                     i = 0
                     while i < 10000
                      invoker
                      i+=1
                     end
                   end


3321 190     b        ruby.__dash_e__::block_0$RUBY$__file__ (83 bytes)
  @ 6   org.jruby.RubyFixnum::op_lt (22 bytes)   inline (hot)
  @ 66   org.jruby.RubyBasicObject::isTrue (15 bytes)    inline (hot)
  @ 6   ruby.__dash_e__::method__1$RUBY$invoker (9 bytes)    inline (hot)
    @ 6   ruby.__dash_e__::method__0$RUBY$foo (7 bytes)    inline (hot)
  @ 5   org.jruby.RubyFixnum::op_plus_one (31 bytes)    inline (hot)
def foo; 1; end
                   def invoker; foo; end
                   N.times do
                     i = 0
                     while i < 10000
                      invoker
                      i+=1
                     end
                   end


3321 190     b        ruby.__dash_e__::block_0$RUBY$__file__ (83 bytes)
  @ 6   org.jruby.RubyFixnum::op_lt (22 bytes)   inline (hot)
  @ 66   org.jruby.RubyBasicObject::isTrue (15 bytes)    inline (hot)
  @ 6   ruby.__dash_e__::method__1$RUBY$invoker (9 bytes)    inline (hot)
    @ 6   ruby.__dash_e__::method__0$RUBY$foo (7 bytes)    inline (hot)
  @ 5   org.jruby.RubyFixnum::op_plus_one (31 bytes)    inline (hot)
def foo; 1; end
                   def invoker; foo; end
                   N.times do
                     i = 0
                     while i < 10000
                      invoker
                      i+=1
                     end
                   end


3321 190     b        ruby.__dash_e__::block_0$RUBY$__file__ (83 bytes)
  @ 6   org.jruby.RubyFixnum::op_lt (22 bytes)   inline (hot)
  @ 66   org.jruby.RubyBasicObject::isTrue (15 bytes)    inline (hot)
  @ 6   ruby.__dash_e__::method__1$RUBY$invoker (9 bytes)    inline (hot)
    @ 6   ruby.__dash_e__::method__0$RUBY$foo (7 bytes)    inline (hot)
  @ 5   org.jruby.RubyFixnum::op_plus_one (31 bytes)    inline (hot)
def foo; 1; end
                   def invoker; foo; end
                   N.times do
                     i = 0
                     while i < 10000
                      invoker
                      i+=1
                     end
                   end


3321 190     b        ruby.__dash_e__::block_0$RUBY$__file__ (83 bytes)
  @ 6   org.jruby.RubyFixnum::op_lt (22 bytes)   inline (hot)
  @ 66   org.jruby.RubyBasicObject::isTrue (15 bytes)    inline (hot)
  @ 6   ruby.__dash_e__::method__1$RUBY$invoker (9 bytes)    inline (hot)
    @ 6   ruby.__dash_e__::method__0$RUBY$foo (7 bytes)    inline (hot)
  @ 5   org.jruby.RubyFixnum::op_plus_one (31 bytes)    inline (hot)
def foo; 1; end
                   def invoker; foo; end
                   N.times do
                     i = 0
                     while i < 10000
                      invoker
                      i+=1
                     end
                   end


3321 190     b        ruby.__dash_e__::block_0$RUBY$__file__ (83 bytes)
  @ 6   org.jruby.RubyFixnum::op_lt (22 bytes)   inline (hot)
  @ 66   org.jruby.RubyBasicObject::isTrue (15 bytes)    inline (hot)
  @ 6   ruby.__dash_e__::method__1$RUBY$invoker (9 bytes)    inline (hot)
    @ 6   ruby.__dash_e__::method__0$RUBY$foo (7 bytes)    inline (hot)
  @ 5   org.jruby.RubyFixnum::op_plus_one (31 bytes)    inline (hot)
def foo; 1; end
                   def invoker; foo; end
                   N.times do
                     i = 0
                     while i < 10000
                      invoker
                      i+=1
                     end
                   end


3321 190     b        ruby.__dash_e__::block_0$RUBY$__file__ (83 bytes)
  @ 6   org.jruby.RubyFixnum::op_lt (22 bytes)   inline (hot)
  @ 66   org.jruby.RubyBasicObject::isTrue (15 bytes)    inline (hot)
  @ 6   ruby.__dash_e__::method__1$RUBY$invoker (9 bytes)    inline (hot)
    @ 6   ruby.__dash_e__::method__0$RUBY$foo (7 bytes)    inline (hot)
  @ 5   org.jruby.RubyFixnum::op_plus_one (31 bytes)    inline (hot)
def foo; 1; end
                   def invoker; foo; end
                   N.times do
                     i = 0
                     while i < 10000
                      invoker
                      i+=1
                     end
                   end


3321 190     b        ruby.__dash_e__::block_0$RUBY$__file__ (83 bytes)
  @ 6   org.jruby.RubyFixnum::op_lt (22 bytes)   inline (hot)
  @ 66   org.jruby.RubyBasicObject::isTrue (15 bytes)    inline (hot)
  @ 6   ruby.__dash_e__::method__1$RUBY$invoker (9 bytes)    inline (hot)
    @ 6   ruby.__dash_e__::method__0$RUBY$foo (7 bytes)    inline (hot)
  @ 5   org.jruby.RubyFixnum::op_plus_one (31 bytes)    inline (hot)
Does It Help?
JRuby/Java 6   JRuby/Java 7
JRuby/Java 6                   JRuby/Java 7
                        Times Faster than Ruby 1.9.3
  5



3.75



 2.5



1.25



  0
       base64      richards        neural      mandelbrot     redblack
JRuby/Java 6                     JRuby/Java 7
                            Times Faster than Ruby 1.9.3
  5



3.75



 2.5

                                    1.914          1.806
                    1.538                                         1.565
1.25   1.346




  0
         base64      richards          neural      mandelbrot      redblack
JRuby/Java 6                     JRuby/Java 7
                                 Times Faster than Ruby 1.9.3
  5


                                                                4.226           4.32
3.75
                                                 3.66
                                 3.44


 2.5           2.658


                                         1.914          1.806
                         1.538                                          1.565
1.25   1.346




  0
         base64           richards          neural      mandelbrot       redblack
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/
Ruby 1.8.7   Ruby 1.9.3          Ruby 2.0.0   JRuby

100000



 75000



 50000



 25000

                                         19590.7
                        11439
              4750
     0
                         Iterations per second
And Rails?
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!
• JRuby BOF in Room C at 6:30PM
JRUBY BOOK
Thank you!

• @headius
• jruby.org
• torquebox.org

More Related Content

What's hot

Demistifying OSGi - Colombo Java Meetup 2013
Demistifying OSGi - Colombo Java Meetup 2013Demistifying OSGi - Colombo Java Meetup 2013
Demistifying OSGi - Colombo Java Meetup 2013Sameera Jayasoma
 
JRuby Jam Session
JRuby Jam Session JRuby Jam Session
JRuby Jam Session Engine Yard
 
GOTO Night with Charles Nutter Slides
GOTO Night with Charles Nutter SlidesGOTO Night with Charles Nutter Slides
GOTO Night with Charles Nutter SlidesAlexandra Masterson
 
JavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesJavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesCharles Nutter
 
JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011Charles Nutter
 
Java Tools and Techniques for Solving Tricky Problem
Java Tools and Techniques for Solving Tricky ProblemJava Tools and Techniques for Solving Tricky Problem
Java Tools and Techniques for Solving Tricky ProblemWill Iverson
 
State of the art - server side JavaScript - web-5 2012
State of the art - server side JavaScript - web-5 2012State of the art - server side JavaScript - web-5 2012
State of the art - server side JavaScript - web-5 2012Alexandre Morgaut
 
Smartcard Vulnerabilities In Modern Banking Malwaremalware
Smartcard Vulnerabilities In Modern Banking MalwaremalwareSmartcard Vulnerabilities In Modern Banking Malwaremalware
Smartcard Vulnerabilities In Modern Banking MalwaremalwarePositive Hack Days
 
Jvm performance tuning
Jvm performance tuningJvm performance tuning
Jvm performance tuningIgor Igoroshka
 
Project Build With Maven
Project Build With MavenProject Build With Maven
Project Build With Mavenelliando dias
 
JAVA AND ANDROID OS_PRESENTATION
JAVA AND ANDROID OS_PRESENTATIONJAVA AND ANDROID OS_PRESENTATION
JAVA AND ANDROID OS_PRESENTATIONBenjamin Agboola
 
Torquebox - O melhor dos dois mundos
Torquebox - O melhor dos dois mundosTorquebox - O melhor dos dois mundos
Torquebox - O melhor dos dois mundosBruno Oliveira
 
groovy and concurrency
groovy and concurrencygroovy and concurrency
groovy and concurrencyPaul King
 
Jdk Tools For Performance Diagnostics
Jdk Tools For Performance DiagnosticsJdk Tools For Performance Diagnostics
Jdk Tools For Performance DiagnosticsDror Bereznitsky
 
Java Runtime: повседневные обязанности JVM
Java Runtime: повседневные обязанности JVMJava Runtime: повседневные обязанности JVM
Java Runtime: повседневные обязанности JVModnoklassniki.ru
 
Introduction httpClient on Java11 / Java11時代のHTTPアクセス再入門
Introduction httpClient on Java11 / Java11時代のHTTPアクセス再入門Introduction httpClient on Java11 / Java11時代のHTTPアクセス再入門
Introduction httpClient on Java11 / Java11時代のHTTPアクセス再入門tamtam180
 

What's hot (20)

ClassLoader Leaks
ClassLoader LeaksClassLoader Leaks
ClassLoader Leaks
 
Demistifying OSGi - Colombo Java Meetup 2013
Demistifying OSGi - Colombo Java Meetup 2013Demistifying OSGi - Colombo Java Meetup 2013
Demistifying OSGi - Colombo Java Meetup 2013
 
JRuby Jam Session
JRuby Jam Session JRuby Jam Session
JRuby Jam Session
 
GOTO Night with Charles Nutter Slides
GOTO Night with Charles Nutter SlidesGOTO Night with Charles Nutter Slides
GOTO Night with Charles Nutter Slides
 
JavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesJavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for Dummies
 
JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011
 
HotSpotコトハジメ
HotSpotコトハジメHotSpotコトハジメ
HotSpotコトハジメ
 
Java Tools and Techniques for Solving Tricky Problem
Java Tools and Techniques for Solving Tricky ProblemJava Tools and Techniques for Solving Tricky Problem
Java Tools and Techniques for Solving Tricky Problem
 
State of the art - server side JavaScript - web-5 2012
State of the art - server side JavaScript - web-5 2012State of the art - server side JavaScript - web-5 2012
State of the art - server side JavaScript - web-5 2012
 
Smartcard Vulnerabilities In Modern Banking Malwaremalware
Smartcard Vulnerabilities In Modern Banking MalwaremalwareSmartcard Vulnerabilities In Modern Banking Malwaremalware
Smartcard Vulnerabilities In Modern Banking Malwaremalware
 
Jvm performance tuning
Jvm performance tuningJvm performance tuning
Jvm performance tuning
 
Project Build With Maven
Project Build With MavenProject Build With Maven
Project Build With Maven
 
JAVA AND ANDROID OS_PRESENTATION
JAVA AND ANDROID OS_PRESENTATIONJAVA AND ANDROID OS_PRESENTATION
JAVA AND ANDROID OS_PRESENTATION
 
Torquebox - O melhor dos dois mundos
Torquebox - O melhor dos dois mundosTorquebox - O melhor dos dois mundos
Torquebox - O melhor dos dois mundos
 
groovy and concurrency
groovy and concurrencygroovy and concurrency
groovy and concurrency
 
Jdk Tools For Performance Diagnostics
Jdk Tools For Performance DiagnosticsJdk Tools For Performance Diagnostics
Jdk Tools For Performance Diagnostics
 
Java Runtime: повседневные обязанности JVM
Java Runtime: повседневные обязанности JVMJava Runtime: повседневные обязанности JVM
Java Runtime: повседневные обязанности JVM
 
Jvm internals
Jvm internalsJvm internals
Jvm internals
 
Introduction httpClient on Java11 / Java11時代のHTTPアクセス再入門
Introduction httpClient on Java11 / Java11時代のHTTPアクセス再入門Introduction httpClient on Java11 / Java11時代のHTTPアクセス再入門
Introduction httpClient on Java11 / Java11時代のHTTPアクセス再入門
 
JCR In 10 Minutes
JCR In 10 MinutesJCR In 10 Minutes
JCR In 10 Minutes
 

Viewers also liked

Abstraction of JRuby Kaigi2010
Abstraction of  JRuby Kaigi2010Abstraction of  JRuby Kaigi2010
Abstraction of JRuby Kaigi2010Koichiro Ohba
 
Introduction to JRuby
Introduction to JRubyIntroduction to JRuby
Introduction to JRubyAmit Solanki
 
J Ruby Kungfu Rails
J Ruby   Kungfu RailsJ Ruby   Kungfu Rails
J Ruby Kungfu RailsDaniel Lv
 
Introduction to JRuby
Introduction to JRubyIntroduction to JRuby
Introduction to JRubyajuckel
 
jRuby: The best of both worlds
jRuby: The best of both worldsjRuby: The best of both worlds
jRuby: The best of both worldsChristopher Spring
 
Focuslight, Jobs and OSS - HackGirls bar vol.2
Focuslight, Jobs and OSS - HackGirls bar vol.2Focuslight, Jobs and OSS - HackGirls bar vol.2
Focuslight, Jobs and OSS - HackGirls bar vol.2Koichiro Ohba
 

Viewers also liked (9)

Abstraction of JRuby Kaigi2010
Abstraction of  JRuby Kaigi2010Abstraction of  JRuby Kaigi2010
Abstraction of JRuby Kaigi2010
 
Megyünk a Balcsira?
Megyünk a Balcsira?Megyünk a Balcsira?
Megyünk a Balcsira?
 
S
SS
S
 
Introduction to JRuby
Introduction to JRubyIntroduction to JRuby
Introduction to JRuby
 
J Ruby Kungfu Rails
J Ruby   Kungfu RailsJ Ruby   Kungfu Rails
J Ruby Kungfu Rails
 
Introduction to JRuby
Introduction to JRubyIntroduction to JRuby
Introduction to JRuby
 
Intro to J Ruby
Intro to J RubyIntro to J Ruby
Intro to J Ruby
 
jRuby: The best of both worlds
jRuby: The best of both worldsjRuby: The best of both worlds
jRuby: The best of both worlds
 
Focuslight, Jobs and OSS - HackGirls bar vol.2
Focuslight, Jobs and OSS - HackGirls bar vol.2Focuslight, Jobs and OSS - HackGirls bar vol.2
Focuslight, Jobs and OSS - HackGirls bar vol.2
 

Similar to Why JRuby? - RubyConf 2012

GlassFish can support multiple Ruby frameworks ... really ?
GlassFish can support multiple Ruby frameworks ... really ?GlassFish can support multiple Ruby frameworks ... really ?
GlassFish can support multiple Ruby frameworks ... really ?Arun Gupta
 
Glass fish rubyconf-india-2010-Arun gupta
Glass fish rubyconf-india-2010-Arun gupta Glass fish rubyconf-india-2010-Arun gupta
Glass fish rubyconf-india-2010-Arun gupta ThoughtWorks
 
Jruby synergy-of-ruby-and-java
Jruby synergy-of-ruby-and-javaJruby synergy-of-ruby-and-java
Jruby synergy-of-ruby-and-javaKeith Bennett
 
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
 
JRuby @ Boulder Ruby
JRuby @ Boulder RubyJRuby @ Boulder Ruby
JRuby @ Boulder RubyNick Sieger
 
Core java 5 days workshop stuff
Core java 5 days workshop stuffCore java 5 days workshop stuff
Core java 5 days workshop stuffRajiv Gupta
 
Monkeybars in the Manor
Monkeybars in the ManorMonkeybars in the Manor
Monkeybars in the Manormartinbtt
 
Dynamic Languages & Web Frameworks in GlassFish
Dynamic Languages & Web Frameworks in GlassFishDynamic Languages & Web Frameworks in GlassFish
Dynamic Languages & Web Frameworks in GlassFishIndicThreads
 
JRuby talk / 26.03.2014 / @vbalazs
JRuby talk / 26.03.2014 / @vbalazsJRuby talk / 26.03.2014 / @vbalazs
JRuby talk / 26.03.2014 / @vbalazsBalázs Varga
 
Bitter Java, Sweeten with JRuby
Bitter Java, Sweeten with JRubyBitter Java, Sweeten with JRuby
Bitter Java, Sweeten with JRubyBrian Sam-Bodden
 
Introduction to java
Introduction to java Introduction to java
Introduction to java Sandeep Rawat
 
JRoR Deploying Rails on JRuby
JRoR Deploying Rails on JRubyJRoR Deploying Rails on JRuby
JRoR Deploying Rails on JRubyelliando dias
 
JRuby - The Perfect Alternative
JRuby - The Perfect AlternativeJRuby - The Perfect Alternative
JRuby - The Perfect AlternativeRam Vijapurapu
 
JRuby - Programmer's Best Friend on JVM
JRuby - Programmer's Best Friend on JVMJRuby - Programmer's Best Friend on JVM
JRuby - Programmer's Best Friend on JVMRaimonds Simanovskis
 
Behind the Scenes at LiveJournal: Scaling Storytime
Behind the Scenes at LiveJournal: Scaling StorytimeBehind the Scenes at LiveJournal: Scaling Storytime
Behind the Scenes at LiveJournal: Scaling StorytimeSergeyChernyshev
 

Similar to Why JRuby? - RubyConf 2012 (20)

Euruko 2012 - JRuby
Euruko 2012 - JRubyEuruko 2012 - JRuby
Euruko 2012 - JRuby
 
GlassFish can support multiple Ruby frameworks ... really ?
GlassFish can support multiple Ruby frameworks ... really ?GlassFish can support multiple Ruby frameworks ... really ?
GlassFish can support multiple Ruby frameworks ... really ?
 
Glass fish rubyconf-india-2010-Arun gupta
Glass fish rubyconf-india-2010-Arun gupta Glass fish rubyconf-india-2010-Arun gupta
Glass fish rubyconf-india-2010-Arun gupta
 
Jruby synergy-of-ruby-and-java
Jruby synergy-of-ruby-and-javaJruby synergy-of-ruby-and-java
Jruby synergy-of-ruby-and-java
 
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)
 
JRuby @ Boulder Ruby
JRuby @ Boulder RubyJRuby @ Boulder Ruby
JRuby @ Boulder Ruby
 
Core java 5 days workshop stuff
Core java 5 days workshop stuffCore java 5 days workshop stuff
Core java 5 days workshop stuff
 
Monkeybars in the Manor
Monkeybars in the ManorMonkeybars in the Manor
Monkeybars in the Manor
 
Dynamic Languages & Web Frameworks in GlassFish
Dynamic Languages & Web Frameworks in GlassFishDynamic Languages & Web Frameworks in GlassFish
Dynamic Languages & Web Frameworks in GlassFish
 
JRuby talk / 26.03.2014 / @vbalazs
JRuby talk / 26.03.2014 / @vbalazsJRuby talk / 26.03.2014 / @vbalazs
JRuby talk / 26.03.2014 / @vbalazs
 
Bitter Java, Sweeten with JRuby
Bitter Java, Sweeten with JRubyBitter Java, Sweeten with JRuby
Bitter Java, Sweeten with JRuby
 
Introduction to java
Introduction to java Introduction to java
Introduction to java
 
JRoR Deploying Rails on JRuby
JRoR Deploying Rails on JRubyJRoR Deploying Rails on JRuby
JRoR Deploying Rails on JRuby
 
Understanding the Dalvik Virtual Machine
Understanding the Dalvik Virtual MachineUnderstanding the Dalvik Virtual Machine
Understanding the Dalvik Virtual Machine
 
First Day With J Ruby
First Day With J RubyFirst Day With J Ruby
First Day With J Ruby
 
JRuby Basics
JRuby BasicsJRuby Basics
JRuby Basics
 
JRuby - The Perfect Alternative
JRuby - The Perfect AlternativeJRuby - The Perfect Alternative
JRuby - The Perfect Alternative
 
Practical JRuby
Practical JRubyPractical JRuby
Practical JRuby
 
JRuby - Programmer's Best Friend on JVM
JRuby - Programmer's Best Friend on JVMJRuby - Programmer's Best Friend on JVM
JRuby - Programmer's Best Friend on JVM
 
Behind the Scenes at LiveJournal: Scaling Storytime
Behind the Scenes at LiveJournal: Scaling StorytimeBehind the Scenes at LiveJournal: Scaling Storytime
Behind the Scenes at LiveJournal: Scaling Storytime
 

More from Charles 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
 
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
 
JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015Charles Nutter
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaCharles Nutter
 
Open Source Software Needs You!
Open Source Software Needs You!Open Source Software Needs You!
Open Source Software Needs You!Charles Nutter
 
InvokeBinder: Fluent Programming for Method Handles
InvokeBinder: Fluent Programming for Method HandlesInvokeBinder: Fluent Programming for Method Handles
InvokeBinder: Fluent Programming for Method HandlesCharles Nutter
 
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
 
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
 

More from Charles Nutter (20)

The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018
 
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
 
JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible Java
 
Open Source Software Needs You!
Open Source Software Needs You!Open Source Software Needs You!
Open Source Software Needs You!
 
InvokeBinder: Fluent Programming for Method Handles
InvokeBinder: Fluent Programming for Method HandlesInvokeBinder: Fluent Programming for Method Handles
InvokeBinder: Fluent Programming for Method Handles
 
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
 
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
 

Recently uploaded

How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 

Recently uploaded (20)

How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 

Why JRuby? - RubyConf 2012

  • 2. Who? Thomas Charlie @tom_enebo @headius
  • 4. JRuby is Ruby! * 1.8.7 & 1.9.3 compatibility drop-in replacement * see next slide
  • 5. *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...
  • 6. JRuby is Ruby ...and then some?
  • 7. Announcing JRuby 1.7.0 • Ruby 1.9.3 compat (--1.8 for 1.8.7) • Java 7 invokedynamic support • Much awesomeness over 1.6.x
  • 8. Getting Started 1. Install a JVM 2. rvm install jruby 3. Profit! % jruby -e ‘puts “wowee”’
  • 10. JRuby Team Charlie Tom Nick Hiro Marcin Nahi Wayne Subbu Douglas Douglas Douglas Contribs Douglas Douglas Douglas Douglas Douglas Other Douglas OpenJDK Android JVMs
  • 11. JRuby JRuby Yoko JVM J. Rose OS (libc, ...)
  • 12. MRI nobu MRI OS (libc, ...)
  • 13. JRuby JRuby Yoko JVM J. Rose OS (libc, ...)
  • 14. We get it for Free! JVM J. Rose Garbage Profiled Native JIT Optimizations Collection Native Tooling Cross Platform Threading
  • 15. Profile: John Rose • JVM Engineer since 1997 • Invented C* Language • JSR 292 lead
  • 16. JVM over time (what if we were lazy?)
  • 17. Go Java Go! 300% for free JRuby 1.0.3 (bm_red_black_tree.rb) 30 22.5 15 7.5 0 Java 1.4 Java 5 Java 6 Java 7
  • 18. Go Java Go! 300% for free JRuby 1.0.3 (bm_red_black_tree.rb) MRI 1.8 30 22.5 15 7.5 0 Java 1.4 Java 5 Java 6 Java 7
  • 21. JVM is everywhere • Unix++, Windows • Exotic platforms: zLinux, OpenVMS, AS/400 • Mobile: Android’s Dalvik, Embedded JVMs
  • 22.
  • 23. Java bytecode == portability
  • 24. actionmailer-javamail, active_documentum, activerecord-jdbc-adapter, activerecord-jdbcdbf-adapter, activerecord-jdbcderby-adapter, activerecord-jdbch2- adapter, activerecord-jdbchsqldb-adapter, activerecord-jdbcmssql-adapter, activerecord-jdbcmysql-adapter, activerecord-jdbcpostgresql-adapter, activerecord- jdbcsqlite3-adapter, activerecord-netezza-adapter, activerecord-vertica-adapter, akephalos, akephalos-nerian, akephalos2, akka-actor-jars, akka-remote-jars, akubra_llstore_migrate, Antwrap, async-http-client-jars, atomic, atoulme-Antwrap, autotest-java, bbrowning-deltacloud-client, bbrowning-deltacloud-core, bcrypt-ruby, bee_java, berkeley-db-java-jars, bert, bio-maf, blockenspiel, boc, bond, bosdk, bouncy-castle-java, boxed-geminabox, brute-fuzzy, bryanl-gherkin, bson, buby, buildr, buildr-resolver, buildrizpack, butternut, capistrano-java, capybara-java_script_lint, carrierwave-neo4j, carrierwave_imagevoodoo, cassandra- jars, chrest, cloby, commons-io-jars, concurrently, contextual, coupler, cucumber-java, cucumber-jvm, cuke4duke, cuuid, dm-ldap-adapter, dm-lucene-adapter, do-jdbc_sqlserver, do_derby, do_h2, do_hsqldb, do_jdbc, do_mysql, do_openedge, do_oracle, do_postgres, do_sqlite3, do_sqlserver, doubleshot, dripdrop, dubious, duby, engineyard-visualvm, epall-limelight, errbit_zmq_handler, eurydice, euston, euston-daemons, euston-eventstore, euston-projections, euston- rabbitmq, euston-websites, eventmachine, excemel, faye-websocket, ffi, fig, file-find, fishwife, foreman, forkit, forkjoin, gamelan, gemshit, geoip-jars, get_back, gherkin, glassfish, gravitext-util, gravitext-xmlprod, grizzly, guava-jars, hadoop-find, hashdot-test-daemon, hiredis, hitimes, hope, hostor, hot_bunnies, hourglass, hpricot, http_parser.rb, inline_javascript, iudex, iudex-async-httpclient, iudex-barc, iudex-brutefuzzy-protobuf, iudex-brutefuzzy-service, iudex-char-detector, iudex-core, iudex-da, iudex-filter, iudex-html, iudex-http, iudex-http-test, iudex-httpclient-3, iudex-jetty-httpclient, iudex-rome, iudex-simhash, iudex-worker, ivy-jars, iyyov, jactive_support, java-autotest, java-inline, java2ruby-xmldsig, java_bin, java_inline, java_override, java_properties, java_streamify, java_testing_guff, javabean_xml, javaclass, javaeye4r, javagems, javajake, javaobj, javaobjs, javaobs, javaparse, javasand, javascript-securehash-rails, javascript-state- machine-rails, javascript_auto_include, javascript_eraser, javascript_features, javascript_i18n, javascript_localize, javascript_safe_logger, javascript_util_asset_pack, javascripto, javascripto-rails, jdbc-derby, jdbc-hsqldb, jdbc-jtds, jdbc-openedge, jdbc-openedge-internal, jdbc-postgres, jdbc-sqlite3, jedis-jars, jena-jruby, jessica, jettr, jetty, jetty-jsp, jgeoip, jms4r, jpdfer, jrack_handlers, jrtm, jruby-activemq, jruby-akka_jars, jruby-elasticsearch_jars, jruby- httpclient, jruby-launcher, jruby-management, jruby-metrics, jruby-pageant, jruby-vijava, jruby_gc_stats, jruby_sandbox, jruby_threach, jrubyconf-button, jsmetric4java, json, json-jruby, jsound, kb-activerecord-jdbc-adapter, kirk, kyotocabinet-java, ladle, latex-decode, launchy, libnotify, limelight, linecache, logback, logback-jars, looksee, lumix, mack-javascript, markdownj, maven_irb_plugin, metrics-core-jars, metrics-java, mguymon-buildr, mikka, mini_aether, mirah, mirah_model, miso-java, mixology, mm_mq, mongrel, msgpack-idl-java, msgpack-jruby, multimeter, naether, nanoc-javascript-concatenator, neo4j, neo4j-admin, neo4j-advanced, neo4j-community, neo4j-core, neo4j-enterprise, neo4j-spatial, neo4j-will_paginate, neo4j-wrapper, netty-jars, ning-compress-jars, nio4r, nokogiri, nokogiri-fitzsimmons, nokogiri-maven, nosqoop4u, ontomde-demo-java5, ontomde-java, ontomde-java-frontend, ontomde-uml2-java, ontomde-uml2- kbjava, open_nlp, pacer, pacer-dex, pacer-neo4j, pacer-orient, pelops-jars, persvr, pg_array_parser, protobuf-jars, pry, puma, qtjruby-core, qwirk_active_mq_adapter, qwirk_jms_adapter, rabbitmqadmin-cli, ragweed, rails_javascript_helpers, rakejava, rave, rcov, realityforge-jekyll, realityforge- jekylltask, redcar-bundles, redcar-clojure, redcar-filter-through-command, redcar-groovy, redcar-icons, redcar-javamateview, redcar-javascript, redcar-mirah, redcar-svnkit, redcar-xulrunner-win, RedCloth, refinerycms-javascripts, reigns, revo-nokogiri, rika, rjack-async-httpclient, rjack-commons-codec, rjack- commons-dbcp, rjack-commons-dbutils, rjack-commons-pool, rjack-httpclient-3, rjack-httpclient-4, rjack-icu, rjack-jackson, rjack-jdom, rjack-jets3t, rjack-jetty, rjack-jetty-jsp, rjack-jms, rjack-jms-spec, rjack-logback, rjack-lucene, rjack-maven, rjack-mina, rjack-nekohtml, rjack-protobuf, rjack-qpid-client, rjack-rome, rjack-slf4j, rjack-solr, rjack-tarpit, rjack-xerces, rmagick4j, rmodbus, rtm-javatmapi, rtm-majortom, rtm-ontopia, rtm-tinytim, rtm-tmql, rubeus, rubinius-core- api, ruby-blockcache, ruby-debug-base, ruby-maven, ruby2java, rubydoop, rubyjedi-nokogiri_java, scala-inline, scala-library-jars, scriptty, slf4j, slf4j-jars, slyphon- zookeeper, slyphon-zookeeper_jar, smackr, smartimage, SNMP4JR, solr_sail, spiegela-jruby-httpclient, sproutcore, spymemcached, sqldroid, steamcannon- deltacloud-client, steamcannon-deltacloud-core, stilts-stomp-client, supermarket, svm_toolkit, swt, theduke, thick, to-javascript, torquebox-base, torquebox- cache, torquebox-configure, torquebox-container-foundation, torquebox-core, torquebox-messaging, torquebox-messaging-container, torquebox-naming, torquebox-naming-container, torquebox-security, torquebox-server, torquebox-vfs, torquebox-web, twitter4j4r, UDJrb, unageanu-javaclass, unimidi, universe- javascript, url_escape, weakling, webbit-jars, wildnet-jackson, wildnet-netty, wildnet-server, wildsonet-hazelcast, wildsonet-netty, wildsonet-server, wildsonet- streamer, wrest, wrong, xdojava, xqruby, zookeeper
  • 25. actionmailer-javamail, active_documentum, activerecord-jdbc-adapter, activerecord-jdbcdbf-adapter, activerecord-jdbcderby-adapter, activerecord-jdbch2- adapter, activerecord-jdbchsqldb-adapter, activerecord-jdbcmssql-adapter, activerecord-jdbcmysql-adapter, activerecord-jdbcpostgresql-adapter, activerecord- jdbcsqlite3-adapter, activerecord-netezza-adapter, activerecord-vertica-adapter, akephalos, akephalos-nerian, akephalos2, akka-actor-jars, akka-remote-jars, akubra_llstore_migrate, Antwrap, async-http-client-jars, atomic, atoulme-Antwrap, autotest-java, bbrowning-deltacloud-client, bbrowning-deltacloud-core, bcrypt-ruby, bee_java, berkeley-db-java-jars, bert, bio-maf, blockenspiel, boc, bond, bosdk, bouncy-castle-java, boxed-geminabox, brute-fuzzy, bryanl-gherkin, bson, buby, buildr, buildr-resolver, buildrizpack, butternut, capistrano-java, capybara-java_script_lint, carrierwave-neo4j, carrierwave_imagevoodoo, cassandra- jars, chrest, cloby, commons-io-jars, concurrently, contextual, coupler, cucumber-java, cucumber-jvm, cuke4duke, cuuid, dm-ldap-adapter, dm-lucene-adapter, do-jdbc_sqlserver, do_derby, do_h2, do_hsqldb, do_jdbc, do_mysql, do_openedge, do_oracle, do_postgres, do_sqlite3, do_sqlserver, doubleshot, dripdrop, dubious, duby, engineyard-visualvm, epall-limelight, errbit_zmq_handler, eurydice, euston, euston-daemons, euston-eventstore, euston-projections, euston- rabbitmq, euston-websites, eventmachine, excemel, faye-websocket, ffi, fig, file-find, fishwife, foreman, forkit, forkjoin, gamelan, gemshit, geoip-jars, get_back, gherkin, glassfish, gravitext-util, gravitext-xmlprod, grizzly, guava-jars, hadoop-find, hashdot-test-daemon, hiredis, hitimes, hope, hostor, hot_bunnies, hourglass, hpricot, http_parser.rb, inline_javascript, iudex, iudex-async-httpclient, iudex-barc, iudex-brutefuzzy-protobuf, iudex-brutefuzzy-service, iudex-char-detector, iudex-core, iudex-da, iudex-filter, iudex-html, iudex-http, iudex-http-test, iudex-httpclient-3, iudex-jetty-httpclient, iudex-rome, iudex-simhash, iudex-worker, ivy-jars, iyyov, jactive_support, java-autotest, java-inline, java2ruby-xmldsig, java_bin, java_inline, java_override, java_properties, java_streamify, java_testing_guff, javabean_xml, javaclass, javaeye4r, javagems, javajake, javaobj, javaobjs, javaobs, javaparse, javasand, javascript-securehash-rails, javascript-state- machine-rails, javascript_auto_include, javascript_eraser, javascript_features, javascript_i18n, javascript_localize, javascript_safe_logger, javascript_util_asset_pack, javascripto, javascripto-rails, jdbc-derby, jdbc-hsqldb, jdbc-jtds, jdbc-openedge, jdbc-openedge-internal, jdbc-postgres, jdbc-sqlite3, No build tools! jedis-jars, jena-jruby, jessica, jettr, jetty, jetty-jsp, jgeoip, jms4r, jpdfer, jrack_handlers, jrtm, jruby-activemq, jruby-akka_jars, jruby-elasticsearch_jars, jruby- httpclient, jruby-launcher, jruby-management, jruby-metrics, jruby-pageant, jruby-vijava, jruby_gc_stats, jruby_sandbox, jruby_threach, jrubyconf-button, jsmetric4java, json, json-jruby, jsound, kb-activerecord-jdbc-adapter, kirk, kyotocabinet-java, ladle, latex-decode, launchy, libnotify, limelight, linecache, logback, logback-jars, looksee, lumix, mack-javascript, markdownj, maven_irb_plugin, metrics-core-jars, metrics-java, mguymon-buildr, mikka, mini_aether, mirah, mirah_model, miso-java, mixology, mm_mq, mongrel, msgpack-idl-java, msgpack-jruby, multimeter, naether, nanoc-javascript-concatenator, neo4j, neo4j-admin, neo4j-advanced, neo4j-community, neo4j-core, neo4j-enterprise, neo4j-spatial, neo4j-will_paginate, neo4j-wrapper, netty-jars, ning-compress-jars, nio4r, nokogiri, nokogiri-fitzsimmons, nokogiri-maven, nosqoop4u, ontomde-demo-java5, ontomde-java, ontomde-java-frontend, ontomde-uml2-java, ontomde-uml2- kbjava, open_nlp, pacer, pacer-dex, pacer-neo4j, pacer-orient, pelops-jars, persvr, pg_array_parser, protobuf-jars, pry, puma, qtjruby-core, qwirk_active_mq_adapter, qwirk_jms_adapter, rabbitmqadmin-cli, ragweed, rails_javascript_helpers, rakejava, rave, rcov, realityforge-jekyll, realityforge- jekylltask, redcar-bundles, redcar-clojure, redcar-filter-through-command, redcar-groovy, redcar-icons, redcar-javamateview, redcar-javascript, redcar-mirah, redcar-svnkit, redcar-xulrunner-win, RedCloth, refinerycms-javascripts, reigns, revo-nokogiri, rika, rjack-async-httpclient, rjack-commons-codec, rjack- commons-dbcp, rjack-commons-dbutils, rjack-commons-pool, rjack-httpclient-3, rjack-httpclient-4, rjack-icu, rjack-jackson, rjack-jdom, rjack-jets3t, rjack-jetty, rjack-jetty-jsp, rjack-jms, rjack-jms-spec, rjack-logback, rjack-lucene, rjack-maven, rjack-mina, rjack-nekohtml, rjack-protobuf, rjack-qpid-client, rjack-rome, rjack-slf4j, rjack-solr, rjack-tarpit, rjack-xerces, rmagick4j, rmodbus, rtm-javatmapi, rtm-majortom, rtm-ontopia, rtm-tinytim, rtm-tmql, rubeus, rubinius-core- api, ruby-blockcache, ruby-debug-base, ruby-maven, ruby2java, rubydoop, rubyjedi-nokogiri_java, scala-inline, scala-library-jars, scriptty, slf4j, slf4j-jars, slyphon- zookeeper, slyphon-zookeeper_jar, smackr, smartimage, SNMP4JR, solr_sail, spiegela-jruby-httpclient, sproutcore, spymemcached, sqldroid, steamcannon- deltacloud-client, steamcannon-deltacloud-core, stilts-stomp-client, supermarket, svm_toolkit, swt, theduke, thick, to-javascript, torquebox-base, torquebox- cache, torquebox-configure, torquebox-container-foundation, torquebox-core, torquebox-messaging, torquebox-messaging-container, torquebox-naming, torquebox-naming-container, torquebox-security, torquebox-server, torquebox-vfs, torquebox-web, twitter4j4r, UDJrb, unageanu-javaclass, unimidi, universe- javascript, url_escape, weakling, webbit-jars, wildnet-jackson, wildnet-netty, wildnet-server, wildsonet-hazelcast, wildsonet-netty, wildsonet-server, wildsonet- streamer, wrest, wrong, xdojava, xqruby, zookeeper
  • 26. Libraries Lucene Neo4j Selenium 47k libraries in Maven Hadoop EHCache JMonkeyEngine Sitemesh
  • 27. Languages/Polyglot Clojure Scala Jython Rhino/Nashorn/ Groovy DynJS (JavaScript) Micro Focus JVM Visual COBOL
  • 28. Polyglot • Use right tool for the right job • Running in the same VM • Another dimension of libraries
  • 29. GC
  • 30. GC Matters • Applications grow over time • Ruby is very object-heavy • Multiprocess multiplies the problem • You will eventually have issues
  • 31. JVM GC • Wide array of options • Many GCs to choose from • Scales up to massive heaps • Best GCs in the world!
  • 32. OpenJDK GCs • Parallel: multi-core stop-the-world • Concurrent: STW young, concurrent old • G1: concurrent young and old • Serial: single-thread STW
  • 33. Object Homogeneity • Everything expressed as JVM objects • Everything shares the same infrastructure • Including extensions, libraries, etc • One GC to rule them all • And one standard memory model
  • 34. gc_demo.rb • Heavy GC, mix of old and young • Steadily growing heap use
  • 35. 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 }
  • 36. Ruby 1.9.3 JRuby 8000 6000 4000 2000 0 GC count
  • 37. Ruby 1.9.3 JRuby 10000 1000 100 10 1 GC count
  • 38. 15 Ruby 1.9.3 JRuby 11.25 7.5 3.75 0 GC time %
  • 39. Ruby 2.0.0 JRuby Time per GC versus heap usage 300ms 225ms Time per GC 150ms 75ms 0ms 188KB/29MB 27MB/127MB 199MB/238MB Heap usage (MRI/JRuby)
  • 40. Ruby 2.0.0 JRuby Time per GC versus heap usage :-( :-( User Unhappiness :-/ :-| :-) 188KB/29MB 27MB/127MB 199MB/238MB Heap usage (MRI/JRuby)
  • 41. Ruby 2.0.0 4,000 3,000 Time Per GC (ms) 2,000 1,000 0 0M 1,250M 2,500M 3,750M 5,000M Heap Size
  • 42. Findings • Lower, more uniform GC times • Reduced or eliminated pauses • Very large heaps are no problem • Predictable, consistent experience
  • 44. Real Parallellism • Ruby thread = JVM thread = native thread • One process can use all cores • One server can handle all requests
  • 45. require 'benchmark' ary = (1..1000000).to_a loop {   puts Benchmark.measure {     10.times {       ary.each {|i|}     }   } }
  • 46. require 'benchmark' ary = (1..1000000).to_a loop {   puts Benchmark.measure {     (1..10).map {       Thread.new {         ary.each {|i|}       }     }.map(&:join)   } }
  • 47.
  • 49. Ruby 1.9 Ruby 1.9 unthreaded threaded
  • 50. Ruby 1.9 Ruby 1.9 unthreaded threaded JRuby unthreaded
  • 51. Ruby 1.9 Ruby 1.9 unthreaded threaded JRuby JRuby unthreaded threaded
  • 52. threaded_reverse Per-iteration time versus thread count 0.8s 0.65s 0.5s 0.35s 0.2s one thread two threads three threads four threads
  • 53. Nonlinear? • More work means more objects • Allocation/GC needs memory bandwidth • No different from multi-process
  • 54.
  • 55. Tools
  • 56. Profiling • Java profilers • VisualVM,YourKit, NetBeans, JXInsight • jruby [--profile | --profile.graph] • jruby -Xreify.classes=true • JVM command-line profilers
  • 57. 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
  • 58. VisualVM • CPU, memory, thread monitoring • CPU and memory profiling • VisualGC • Heap analysis
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 67. JavaFX straight port Simple Clock
  • 68. @minute_hand = Path.new.tap do |mh| Draw minute hand mh.setFill(Color::BLACK) mh.getElements.add MoveTo.new(4, -4) mh.getElements.add ArcTo.new(-1, -1, 0, -4, -4, false, false) mh.getElements.add LineTo.new(0, -radius) mh.getTransforms.add Rotate.new end Implement Java Event class Refresher include EventHandler handler def handle(event); event.source.refresh; end end refresh timeline every 1s Timeline.new.tap do |time| time.setCycleCount Timeline::INDEFINITE time.getKeyFrames.add(Keyframe.new(Duration.millis(1000)), Refresher.new) time.play end
  • 69. getFooBar -> fooBar @minute_hand = Path.new.tap do |mh| mh.setFill(Color::BLACK) was getElements mh.elements.add MoveTo.new(4, -4) mh.elements.add ArcTo.new(-1, -1, 0, -4, -4, false, false) mh.elements.add LineTo.new(0, -radius) mh.transforms.add Rotate.new end was getTransforms class Refresher include EventHandler def handle(event); event.source.refresh; end end Timeline.new.tap do |time| time.setCycleCount Timeline::INDEFINITE time.keyFrames.add(Keyframe.new(Duration.millis(1000)), Refresher.new) time.play end was getKeyFrames
  • 70. setFoo(a) -> foo = a @minute_hand = Path.new.tap do |mh| mh.fill = Color::BLACK was setFill mh.elements.add MoveTo.new(4, -4) mh.elements.add ArcTo.new(-1, -1, 0, -4, -4, false, false) mh.elements.add LineTo.new(0, -radius) mh.transforms.add Rotate.new end class Refresher include EventHandler def handle(event); event.source.refresh; end end Timeline.new.tap do |time| was setCycleCount time.cycleCount = Timeline::INDEFINITE time.keyFrames.add(Keyframe.new(Duration.millis(1000)), Refresher.new) time.play end
  • 71. camelCase -> camel_case @minute_hand = Path.new.tap do |mh| mh.fill = Color::BLACK mh.elements.add MoveTo.new(4, -4) mh.elements.add ArcTo.new(-1, -1, 0, -4, -4, false, false) mh.elements.add LineTo.new(0, -radius) mh.transforms.add Rotate.new end class Refresher include EventHandler def handle(event); event.source.refresh; end end Timeline.new.tap do |time| was cycleCount time.cycle_count = Timeline::INDEFINITE time.key_frames.add(Keyframe.new(Duration.millis(1000)), Refresher.new) time.play end was keyFrames
  • 72. Procs as interfaces @minute_hand = Path.new.tap do |mh| mh.fill = Color::BLACK mh.elements.add MoveTo.new(4, -4) mh.elements.add ArcTo.new(-1, -1, 0, -4, -4, false, false) mh.elements.add LineTo.new(0, -radius) mh.transforms.add Rotate.new end No more extra class Timeline.new.tap do |time| time.cycle_count = Timeline::INDEFINITE time.key_frames.add Keyframe.new(Duration.millis(1000)) {refresh} time.play end
  • 73. Common Adornments ‘add’ becomes ‘<<‘ @minute_hand = Path.new.tap do |mh| mh.fill = Color::BLACK mh.elements << MoveTo.new(4, -4) mh.elements << ArcTo.new(-1, -1, 0, -4, -4, false, false) mh.elements << LineTo.new(0, -radius) mh.transforms << Rotate.new end Timeline.new.tap do |time| time.cycle_count = Timeline::INDEFINITE time.key_frames << Keyframe.new(Duration.millis(1000)) {refresh} time.play end
  • 74. Purugin • Minecraft scripting in JRuby • Clean and simple DSL • Purogo: LOGO for Minecraft
  • 75. 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
  • 76.
  • 79. Native Extensions Suck “Look, nobody enjoys shooting penguins, but if you have to shoot penguins, well, you might as well enjoy it.” - Free Waterfall Sr.
  • 80. Flowchart of Shame Can I write it in Ruby? Script Java? no yes no Does it need Can I use FFI? to be n times faster? no no Native Extension
  • 81. Java Native Extensions • Written in Java • Have same performance as Java • Use same GC as JRuby • First Class Citizens
  • 83. Go Java Go! 300% for free JRuby 1.0.3 (bm_red_black_tree.rb) 30 22.5 15 7.5 0 Java 1.4 Java 5 Java 6 Java 7
  • 84. Go JRuby Go! OpenJDK 8 (bm_red_black_tree.rb) 8 6 4 2 0 1.0.3 1.1.6 1.4.0 1.5.6 1.6.8 1.7.0
  • 85. Severe gains??? OpenJDK 8 (bm_red_black_tree.rb) 9 Severe perf bottleneck(s) 6.75 4.5 2.25 0 1.0.3 1.1.6 1.4.0 1.5.6 1.6.8 1.7.0
  • 86. 1.0.3 & red_black_tree -J-verbose:gc [GC (Allocation Failure) 223608K->96408K(330752K), 0.0159780 secs] [GC (Allocation Failure) 208920K->100792K(335168K), 0.0157550 secs] [GC (Allocation Failure) 213304K->105144K(332160K), 0.0181010 secs] 8.1s [GC (Allocation Failure) 205112K->108920K(334400K), 0.0187580 secs] [GC (Allocation Failure) 208888K->112712K(329152K), 0.0154440 secs] +28 more [GC (Allocation Failure) 313780K->199892K(339072K), 0.0142010 secs] [GC (Allocation Failure) 318420K->204420K(331520K), 0.0175690 secs] 8.4s [GC (Allocation Failure) 306948K->208316K(335680K), 0.0188120 secs] [Full GC (Ergonomics) 208316K->54991K(352256K), 0.2709750 secs] [GC (Allocation Failure) 157519K->58959K(349248K), 0.0120840 secs] +28 more Moar Objects!
  • 87. 1.7.0 & red_black_tree -J-verbose:gc [GC (Allocation Failure) 155729K->39697K(207296K), 0.0072730 secs] 0.963s [GC (Allocation Failure) 160785K->40657K(208320K), 0.0108620 secs] 0.968s [GC (Allocation Failure) 161745K->41649K(210112K), 0.0083760 secs] 0.968s [GC (Allocation Failure) 166193K->39729K(210688K), 0.0070670 secs] 0.99s
  • 88. OpenJDK 8 (bm_red_black_tree.rb) 3 2.25 1.5 0.75 0 1.1.6 1.4.0 1.5.6 1.6.8 1.7.0
  • 89. OpenJDK 8 (bm_red_black_tree.rb) 3 JVM Feature! 2.25 1.5 0.75 0 1.1.6 1.4.0 1.5.6 1.6.8 1.7.0
  • 90. Performance • JRuby compiles Ruby to JVM bytecode • JVM compiles bytecode to native • Best JIT technology in the world • Getting even better with invokedynamic
  • 91. How to Optimize Ruby • Do less work • Reduce dispatch and call overhead • Reduce memory overhead • Find static patterns • Profile running code • Emit optimized version with guards
  • 92. JVM Optimizations • Profiling • Watch code, optimize hottest paths • Inlining • Combine code, optimize as a whole • Escape analysis • Eliminate transient objects
  • 93. def foo; Object.new; end def invoker; foo; end i = 0 while i < 10000   invoker   i+=1 end
  • 94. Inline foo into invoker def invoker; Object.new; end i = 0 while i < 10000   invoker   i+=1 end
  • 95. Inline invoker into loop i = 0 while i < 10000   Object.new   i+=1 end
  • 96. Object is transient i = 0 while i < 10000   i+=1 end
  • 98. Variable i is never read
  • 99. InvokeDynamic • Java 7+ feature • Allows us to teach JVM about Ruby • Dynamic calls can inline • Constants become truly constant • JVM’s best optimizations can work
  • 101. def foo; 1; end def invoker; foo; end N.times do i = 0 while i < 10000    invoker    i+=1 end end
  • 102. $ jruby -J-XX:+UnlockDiagnosticVMOptions -J-XX:+PrintInlining -J-XX:+PrintCompilation script.rb 79 1 b java.lang.String::hashCode (55 bytes) 109 2 b java.util.Properties$LineReader::readLine (452 bytes) @ 48 java.io.Reader::read (9 bytes) never executed @ 62 java.io.FilterInputStream::read (9 bytes) @ 303 java.lang.System::arraycopy (0 bytes) (intrinsic) @ 388 java.io.Reader::read (9 bytes) never executed ....
  • 103. def foo; 1; end def invoker; foo; end N.times do i = 0 while i < 10000    invoker    i+=1 end end 3321 190 b ruby.__dash_e__::block_0$RUBY$__file__ (83 bytes) @ 6 org.jruby.RubyFixnum::op_lt (22 bytes) inline (hot) @ 66 org.jruby.RubyBasicObject::isTrue (15 bytes) inline (hot) @ 6 ruby.__dash_e__::method__1$RUBY$invoker (9 bytes) inline (hot) @ 6 ruby.__dash_e__::method__0$RUBY$foo (7 bytes) inline (hot) @ 5 org.jruby.RubyFixnum::op_plus_one (31 bytes) inline (hot)
  • 104. def foo; 1; end def invoker; foo; end N.times do i = 0 while i < 10000    invoker    i+=1 end end 3321 190 b ruby.__dash_e__::block_0$RUBY$__file__ (83 bytes) @ 6 org.jruby.RubyFixnum::op_lt (22 bytes) inline (hot) @ 66 org.jruby.RubyBasicObject::isTrue (15 bytes) inline (hot) @ 6 ruby.__dash_e__::method__1$RUBY$invoker (9 bytes) inline (hot) @ 6 ruby.__dash_e__::method__0$RUBY$foo (7 bytes) inline (hot) @ 5 org.jruby.RubyFixnum::op_plus_one (31 bytes) inline (hot)
  • 105. def foo; 1; end def invoker; foo; end N.times do i = 0 while i < 10000    invoker    i+=1 end end 3321 190 b ruby.__dash_e__::block_0$RUBY$__file__ (83 bytes) @ 6 org.jruby.RubyFixnum::op_lt (22 bytes) inline (hot) @ 66 org.jruby.RubyBasicObject::isTrue (15 bytes) inline (hot) @ 6 ruby.__dash_e__::method__1$RUBY$invoker (9 bytes) inline (hot) @ 6 ruby.__dash_e__::method__0$RUBY$foo (7 bytes) inline (hot) @ 5 org.jruby.RubyFixnum::op_plus_one (31 bytes) inline (hot)
  • 106. def foo; 1; end def invoker; foo; end N.times do i = 0 while i < 10000    invoker    i+=1 end end 3321 190 b ruby.__dash_e__::block_0$RUBY$__file__ (83 bytes) @ 6 org.jruby.RubyFixnum::op_lt (22 bytes) inline (hot) @ 66 org.jruby.RubyBasicObject::isTrue (15 bytes) inline (hot) @ 6 ruby.__dash_e__::method__1$RUBY$invoker (9 bytes) inline (hot) @ 6 ruby.__dash_e__::method__0$RUBY$foo (7 bytes) inline (hot) @ 5 org.jruby.RubyFixnum::op_plus_one (31 bytes) inline (hot)
  • 107. def foo; 1; end def invoker; foo; end N.times do i = 0 while i < 10000    invoker    i+=1 end end 3321 190 b ruby.__dash_e__::block_0$RUBY$__file__ (83 bytes) @ 6 org.jruby.RubyFixnum::op_lt (22 bytes) inline (hot) @ 66 org.jruby.RubyBasicObject::isTrue (15 bytes) inline (hot) @ 6 ruby.__dash_e__::method__1$RUBY$invoker (9 bytes) inline (hot) @ 6 ruby.__dash_e__::method__0$RUBY$foo (7 bytes) inline (hot) @ 5 org.jruby.RubyFixnum::op_plus_one (31 bytes) inline (hot)
  • 108. def foo; 1; end def invoker; foo; end N.times do i = 0 while i < 10000    invoker    i+=1 end end 3321 190 b ruby.__dash_e__::block_0$RUBY$__file__ (83 bytes) @ 6 org.jruby.RubyFixnum::op_lt (22 bytes) inline (hot) @ 66 org.jruby.RubyBasicObject::isTrue (15 bytes) inline (hot) @ 6 ruby.__dash_e__::method__1$RUBY$invoker (9 bytes) inline (hot) @ 6 ruby.__dash_e__::method__0$RUBY$foo (7 bytes) inline (hot) @ 5 org.jruby.RubyFixnum::op_plus_one (31 bytes) inline (hot)
  • 109. def foo; 1; end def invoker; foo; end N.times do i = 0 while i < 10000    invoker    i+=1 end end 3321 190 b ruby.__dash_e__::block_0$RUBY$__file__ (83 bytes) @ 6 org.jruby.RubyFixnum::op_lt (22 bytes) inline (hot) @ 66 org.jruby.RubyBasicObject::isTrue (15 bytes) inline (hot) @ 6 ruby.__dash_e__::method__1$RUBY$invoker (9 bytes) inline (hot) @ 6 ruby.__dash_e__::method__0$RUBY$foo (7 bytes) inline (hot) @ 5 org.jruby.RubyFixnum::op_plus_one (31 bytes) inline (hot)
  • 110. def foo; 1; end def invoker; foo; end N.times do i = 0 while i < 10000    invoker    i+=1 end end 3321 190 b ruby.__dash_e__::block_0$RUBY$__file__ (83 bytes) @ 6 org.jruby.RubyFixnum::op_lt (22 bytes) inline (hot) @ 66 org.jruby.RubyBasicObject::isTrue (15 bytes) inline (hot) @ 6 ruby.__dash_e__::method__1$RUBY$invoker (9 bytes) inline (hot) @ 6 ruby.__dash_e__::method__0$RUBY$foo (7 bytes) inline (hot) @ 5 org.jruby.RubyFixnum::op_plus_one (31 bytes) inline (hot)
  • 112.
  • 113. JRuby/Java 6 JRuby/Java 7
  • 114. JRuby/Java 6 JRuby/Java 7 Times Faster than Ruby 1.9.3 5 3.75 2.5 1.25 0 base64 richards neural mandelbrot redblack
  • 115. JRuby/Java 6 JRuby/Java 7 Times Faster than Ruby 1.9.3 5 3.75 2.5 1.914 1.806 1.538 1.565 1.25 1.346 0 base64 richards neural mandelbrot redblack
  • 116. JRuby/Java 6 JRuby/Java 7 Times Faster than Ruby 1.9.3 5 4.226 4.32 3.75 3.66 3.44 2.5 2.658 1.914 1.806 1.538 1.565 1.25 1.346 0 base64 richards neural mandelbrot redblack
  • 117. 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/
  • 118. Ruby 1.8.7 Ruby 1.9.3 Ruby 2.0.0 JRuby 100000 75000 50000 25000 19590.7 11439 4750 0 Iterations per second
  • 120.
  • 121.
  • 122.
  • 123. 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! • JRuby BOF in Room C at 6:30PM
  • 125.
  • 126. Thank you! • @headius • jruby.org • torquebox.org

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n