Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Aloha RubyConf 2012 - JRuby

headius
October 09, 2012

Aloha RubyConf 2012 - JRuby

A talk on "Why JRuby" for Aloha RubyConf.

headius

October 09, 2012
Tweet

More Decks by headius

Other Decks in Technology

Transcript

  1. Me • Charles Oliver Nutter • @headius • Java developer

    since 1996 • JRuby developer since 2006 • Red Hat / JBoss polyglot group Monday, October 8, 12
  2. Ruby on JVM • Core classes and runtime in Java

    • Moving parts to Ruby over time • Standard command line • 1.8 and 1.9 compatible • 1.9 default in JRuby 1.7 • Drop in replacement for MRI* Monday, October 8, 12
  3. *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... Monday, October 8, 12
  4. JRuby 1.7 • Ruby 1.9.3 mode by default • Many

    1.9 compat fixes • Numerous perf improvements • Java 7 invokedynamic support • Beginning of new optimizing compiler Monday, October 8, 12
  5. Getting Started • Need a JVM... • rvm install jruby

    • rvm install jruby-1.7.0-RC1 • Download manually • Unpack, edit PATH, done Monday, October 8, 12
  6. def fractal_flipflop w, h = 44, 54 c = 7

    + 42 * w a = [0] * w * h g = d = 0 f = proc do |n| a[c] += 1 o = a.map {|z| " :#"[z, 1] * 2 }.join.scan(/.{#{w * 2}}/) puts "\f" + o.map {|l| l.rstrip }.join("\n") d += 1 - 2 * ((g ^= 1 << n) >> n) c += [1, w, -1, -w][d %= 4] end 1024.times do !!(!!(!!(!!(!!(!!(!!(!!(!!(true... f[0])...f[1])...f[2])... f[3])...f[4])...f[5])... f[6])...f[7])...f[8]) end end Monday, October 8, 12
  7. def fractal_flipflop w, h = 44, 54 c = 7

    + 42 * w a = [0] * w * h g = d = 0 f = proc do |n| a[c] += 1 o = a.map {|z| " :#"[z, 1] * 2 }.join.scan(/.{#{w * 2}}/) puts "\f" + o.map {|l| l.rstrip }.join("\n") d += 1 - 2 * ((g ^= 1 << n) >> n) c += [1, w, -1, -w][d %= 4] end 1024.times do !!(!!(!!(!!(!!(!!(!!(!!(!!(true... f[0])...f[1])...f[2])... f[3])...f[4])...f[5])... f[6])...f[7])...f[8]) end end Monday, October 8, 12
  8. JRuby Team Charlie Tom Nick Hiro Marcin Nahi Wayne Subbu

    Douglas Douglas Contribs Douglas Monday, October 8, 12
  9. JRuby Team Charlie Tom Nick Hiro Marcin Nahi Wayne Subbu

    Douglas Douglas Contribs Douglas Douglas OpenJDK Douglas Douglas Android Douglas Douglas J9 Douglas Douglas Other JVMs Douglas Monday, October 8, 12
  10. JRuby Structure JRuby JVM Threads GC Native JIT C API

    Parser Bytecode JIT Core Classes Java Integ Monday, October 8, 12
  11. JRuby Structure JRuby Parser Bytecode JIT Core Classes Java Integ

    JRuby team can focus on implementing JRuby. Monday, October 8, 12
  12. JRuby Team Doesn’t Have to Work On* • Memory allocation

    • Garbage collectors • Native threading • Cross-platform • Mobile/Embedded VMs • Native JIT • Tooling • Server environments • Native extensions Monday, October 8, 12
  13. We could stop working on JRuby and it would continue

    to get faster. Monday, October 8, 12
  14. Systems • Best Ruby on Windows? • Exotic platforms: zLinux,

    OpenVMS, AS/400 • Android’s Dalvik • Embedded JVMs Monday, October 8, 12
  15. 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 Monday, October 8, 12
  16. 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 No build tools, no native exts required! Monday, October 8, 12
  17. Servers • Any Java server can host Ruby • Trinidad

    • Ruby-style CLI server atop Tomcat • Torquebox • Full Ruby stack atop JBossAS Monday, October 8, 12
  18. Ruby App Rails Rack Sinatra Apache/Nginx Passenger/Thin crond Jobs Resque/

    DelayedJob Tasks god/monit Daemons Monday, October 8, 12
  19. Rails Rack Sinatra Procs Tasks Daemons Jobs HA Clustering Load

    Balancing JBoss AS Web Messaging Scheduling Services TorqueBox AS Monday, October 8, 12
  20. Torquebox • Rack-compatible • Database connectivity • Background daemons •

    Scheduled jobs • Messaging • Asynchronous tasks • Server management • Clustering • In and out-process cache • Web sockets • Authentication • XA Transactions Monday, October 8, 12
  21. Torquebox • Rack-compatible • Database connectivity • Background daemons •

    Scheduled jobs • Messaging • Asynchronous tasks • Server management • Clustering • In and out-process cache • Web sockets • Authentication • XA Transactions All Ruby APIs! Monday, October 8, 12
  22. TorqueBox.configure do ruby do version "1.9" compile_mode "off" debug false

    interactive true profile_api true end end ruby: version: 1.9 compile_mode: off debug: false interactive: true profile_api: true Ruby-friendly Config Monday, October 8, 12
  23. TorqueBox.configure do ... queue '/queues/my_app_queue' topic '/queues/my_app_topic' end application: ..

    queues: /queues/my_app_queue: topics: /queues/my_app_topic: Messaging Monday, October 8, 12
  24. queue = fetch('/queues/foo') queue.publish "A text message" topic = fetch('/topics/foo')

    topic.publish "A text message" queue = TorqueBox::Messaging::Queue.new('/queues/foo') message = queue.receive topic = TorqueBox::Messaging::Topic.new('/topics/foo') message = topic.receive Messaging Monday, October 8, 12
  25. Libraries • 340k versioned jars in Maven central • Compare

    to 35k gems in RubyGems.org • Vast majority have no native code • All usable from JRuby Monday, October 8, 12
  26. JavaFX • Scene graph + optimized graphics • Normal Java

    library now • R.I.P. JavaFX Script • jrubyfx, other projects to wrap it Monday, October 8, 12
  27. @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 @hour_hand = Path.new.tap do |hh| hh.fill = Color::BLACK hh.elements << MoveTo.new(4, -4) hh.elements << ArcTo.new(-1, -1, 0, -4, -4, false, false) hh.elements << LineTo.new(0, -radius/4*3) hh.transforms << Rotate.new end Monday, October 8, 12
  28. Purugin • Minecraft scripting in JRuby • Clean and simple

    DSL • Purogo: LOGO for Minecraft Monday, October 8, 12
  29. 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 Monday, October 8, 12
  30. Threepence • Ruby APIs atop Ardor3D library • Various games

    atop Ardor3D • All-in-one clone from Github • Linux, OS X, Windows, Solaris provided Monday, October 8, 12
  31. require 'example_base' class Box < ExampleBase def initialize super("Box Example")

    end def init_application root.layout do cull_state :back skybox(:sky, 500, 500, 500, 'images/skybox/blue') node(:spinning) do behavior :rotating, Vector3(1, 1, 0.5), 50 box(:left_box, 1, 1, 1) do behavior :rotating, Vector3(0.5, 1, 1), 50 at 0, 0, -3 texture "images/ardor3d_white_256.jpg" end.duplicate_as(:right_box) do at 0, 0, 3 " end end end end end Box.start Monday, October 8, 12
  32. GC Matters • Applications grow over time • Ruby is

    very object-heavy • Multicore MRI multiplies the problem • You will eventually have issues Monday, October 8, 12
  33. JVM GC • Wide array of options • Many GCs

    to choose from • Scales up to massive heaps • Best GCs in the world! Monday, October 8, 12
  34. OpenJDK GCs • Parallel: multi-core stop-the-world • Concurrent: STW young,

    concurrent old • G1: concurrent young and old • Serial: single-thread STW Monday, October 8, 12
  35. gc_demo1.rb • Heavy GC, mix of old and young •

    Steadily growing heap use Monday, October 8, 12
  36. 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 } Monday, October 8, 12
  37. 0 3.75 7.5 11.25 15 GC time % Ruby 1.9.3

    JRuby Monday, October 8, 12
  38. 0ms 75ms 150ms 225ms 300ms 188KB/29MB 27MB/127MB 199MB/238MB Time per

    GC versus heap usage Heap usage (MRI/JRuby) Ruby 2.0.0 JRuby Monday, October 8, 12
  39. 10.times do old_ary = [] 10000.times do old_ary << 'foo'

    new_ary = [] 100000.times do new_ary << 'bar' end end puts "looped" end Monday, October 8, 12
  40. 0 1250 2500 3750 5000 GC time (ms) Ruby 1.9.3

    JRuby Monday, October 8, 12
  41. 0s 0.075s 0.15s 0.225s 0.3s 0 5 10 15 20

    World-stopping GC pause times Pause time Seconds since start JRuby (Concurrent) Ruby 2.0.0 Monday, October 8, 12
  42. 0s 0.075s 0.15s 0.225s 0.3s 0 5 10 15 20

    World-stopping GC pause times Pause time Seconds since start JRuby (Concurrent) Ruby 2.0.0 Pause Times Monday, October 8, 12
  43. 0s 0.075s 0.15s 0.225s 0.3s 0 5 10 15 20

    World-stopping GC pause times Pause time Seconds since start JRuby (Concurrent) Ruby 2.0.0 Pause Times User Happiness :-( Monday, October 8, 12
  44. Findings • Lower, more uniform individual GC time • Lower

    overall GC time • Lower application pause times • More predictable, consistent apps Monday, October 8, 12
  45. Real Parallellism • Ruby thread = JVM thread = native

    thread • One process can use all cores • One server can handle all requests Monday, October 8, 12
  46. require 'benchmark' ary = (1..1000000).to_a loop { puts Benchmark.measure {

    10.times { ary.each {|i|} } } } Monday, October 8, 12
  47. require 'benchmark' ary = (1..1000000).to_a loop { puts Benchmark.measure {

    (1..10).map { Thread.new { ary.each {|i|} } }.map(&:join) } } Monday, October 8, 12
  48. 0.2s 0.35s 0.5s 0.65s 0.8s one thread two threads three

    threads four threads Per-iteration time versus thread count threaded_reverse Monday, October 8, 12
  49. Nonlinear? • More work means more objects • More objects

    needs memory bandwidth • No different from multi-process Monday, October 8, 12
  50. Profiling • Java profilers • VisualVM, YourKit, NetBeans, JXInsight •

    jruby [--profile | --profile.graph] • jruby -Xreify.classes=true • JVM command-line profilers Monday, October 8, 12
  51. 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 Monday, October 8, 12
  52. VisualVM • CPU, memory, thread monitoring • CPU and memory

    profiling • VisualGC • Heap analysis Monday, October 8, 12
  53. Performance • JRuby compiles Ruby to JVM bytecode • JVM

    compiles bytecode to native • Best JIT technology in the world • Getting even better with invokedynamic Monday, October 8, 12
  54. def foo bar end def bar baz end def baz

    # ... end foo baz bar Monday, October 8, 12
  55. def foo bar end def bar baz end def baz

    # ... end foo bar baz JRuby call logic JRuby call logic Kills many JVM optimizations JRuby on Java 5/6 JRuby call logic Monday, October 8, 12
  56. def foo bar end def bar baz end def baz

    # ... end foo bar baz JRuby call logic JRuby call logic Dynamic call logic built into JVM JRuby on Java 7 JRuby call logic X X Monday, October 8, 12
  57. def foo bar end def bar baz end def baz

    # ... end foo bar baz Straight through dispatch path JRuby on Java 7 Monday, October 8, 12
  58. def foo bar end def bar baz end def baz

    # ... end foo bar baz Optimizations (like inlining) can happen! JRuby on Java 7 Monday, October 8, 12
  59. 0x00000001060a1be0: mov %eax,-0x14000(%rsp) 0x00000001060a1be7: push %rbp 0x00000001060a1be8: sub $0x30,%rsp 0x00000001060a1bec:

    mov 0x8(%rcx),%r10d 0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d 0x00000001060a1bf7: jne 0x00000001060a1c39 0x00000001060a1bf9: mov %rcx,%r10 0x00000001060a1bfc: mov 0x10(%r10),%ebp 0x00000001060a1c00: cmp $0xfed77602,%ebp 0x00000001060a1c06: jne 0x00000001060a1c1e 0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax 0x00000001060a1c12: add $0x30,%rsp 0x00000001060a1c16: pop %rbp 0x00000001060a1c17: test %eax,-0xec3c1d(%rip) 0x00000001060a1c1d: retq def foo; 1; end def invoker; foo; end i = 0 while i < 10000 invoker i+=1 end Monday, October 8, 12
  60. 0x00000001060a1be0: mov %eax,-0x14000(%rsp) 0x00000001060a1be7: push %rbp 0x00000001060a1be8: sub $0x30,%rsp 0x00000001060a1bec:

    mov 0x8(%rcx),%r10d 0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d 0x00000001060a1bf7: jne 0x00000001060a1c39 0x00000001060a1bf9: mov %rcx,%r10 0x00000001060a1bfc: mov 0x10(%r10),%ebp 0x00000001060a1c00: cmp $0xfed77602,%ebp 0x00000001060a1c06: jne 0x00000001060a1c1e 0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax 0x00000001060a1c12: add $0x30,%rsp 0x00000001060a1c16: pop %rbp 0x00000001060a1c17: test %eax,-0xec3c1d(%rip) 0x00000001060a1c1d: retq def invoker; 1; end i = 0 while i < 10000 invoker i+=1 end Monday, October 8, 12
  61. 0x00000001060a1be0: mov %eax,-0x14000(%rsp) 0x00000001060a1be7: push %rbp 0x00000001060a1be8: sub $0x30,%rsp 0x00000001060a1bec:

    mov 0x8(%rcx),%r10d 0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d 0x00000001060a1bf7: jne 0x00000001060a1c39 0x00000001060a1bf9: mov %rcx,%r10 0x00000001060a1bfc: mov 0x10(%r10),%ebp 0x00000001060a1c00: cmp $0xfed77602,%ebp 0x00000001060a1c06: jne 0x00000001060a1c1e 0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax 0x00000001060a1c12: add $0x30,%rsp 0x00000001060a1c16: pop %rbp 0x00000001060a1c17: test %eax,-0xec3c1d(%rip) 0x00000001060a1c1d: retq i = 0 while i < 10000 1 i+=1 end Monday, October 8, 12
  62. 0x00000001060a1be0: mov %eax,-0x14000(%rsp) 0x00000001060a1be7: push %rbp 0x00000001060a1be8: sub $0x30,%rsp 0x00000001060a1bec:

    mov 0x8(%rcx),%r10d 0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d 0x00000001060a1bf7: jne 0x00000001060a1c39 0x00000001060a1bf9: mov %rcx,%r10 0x00000001060a1bfc: mov 0x10(%r10),%ebp 0x00000001060a1c00: cmp $0xfed77602,%ebp 0x00000001060a1c06: jne 0x00000001060a1c1e 0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax 0x00000001060a1c12: add $0x30,%rsp 0x00000001060a1c16: pop %rbp 0x00000001060a1c17: test %eax,-0xec3c1d(%rip) 0x00000001060a1c1d: retq i = 0 while i < 10000 i+=1 end Monday, October 8, 12
  63. 0x00000001060a1be0: mov %eax,-0x14000(%rsp) 0x00000001060a1be7: push %rbp 0x00000001060a1be8: sub $0x30,%rsp 0x00000001060a1bec:

    mov 0x8(%rcx),%r10d 0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d 0x00000001060a1bf7: jne 0x00000001060a1c39 0x00000001060a1bf9: mov %rcx,%r10 0x00000001060a1bfc: mov 0x10(%r10),%ebp 0x00000001060a1c00: cmp $0xfed77602,%ebp 0x00000001060a1c06: jne 0x00000001060a1c1e 0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax 0x00000001060a1c12: add $0x30,%rsp 0x00000001060a1c16: pop %rbp 0x00000001060a1c17: test %eax,-0xec3c1d(%rip) 0x00000001060a1c1d: retq Monday, October 8, 12
  64. base64 richards neural mandelbrot redblack 0 1.25 2.5 3.75 5

    Times Faster than Ruby 1.9.3 JRuby/Java 6 JRuby/Java 7 Monday, October 8, 12
  65. base64 richards neural mandelbrot redblack 0 1.25 2.5 3.75 5

    1.346 1.538 1.914 1.806 1.565 Times Faster than Ruby 1.9.3 JRuby/Java 6 JRuby/Java 7 Monday, October 8, 12
  66. base64 richards neural mandelbrot redblack 0 1.25 2.5 3.75 5

    1.346 1.538 1.914 1.806 1.565 2.658 3.44 3.66 4.226 4.32 Times Faster than Ruby 1.9.3 JRuby/Java 6 JRuby/Java 7 Monday, October 8, 12
  67. smooth_sort # Original Author: Keith Schwarz ([email protected]) # # 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/ Monday, October 8, 12
  68. 0 25000 50000 75000 100000 Iterations per second 4750 18376

    57215 90593 11439 Ruby 1.9.3 JRuby Rubinius MacRuby Ruby 1.8.7 Monday, October 8, 12
  69. 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! Monday, October 8, 12