Hi, I'm new to the list though I've been using JRuby for around a year - not for web apps though. We're very happy with the jruby java integration and that was the reason for us to move one of our server apps to jruby (which was previously a java app). Now, after a year we decided we'd try moving one of our rails apps to JRuby as well for easier deployment, better speed and better integration with java (for the future). Unfortunately we've hit some seemingly large obstacles. The first is that view rendering is slower on JRuby, the second is rake assets:precompile. First, the view rendering - these are some results I've come up with trying to replicate a controller/view we have in our real app. The results here are generally slightly better than the reality for us and the view rendering is alot faster in both MRI and JRuby in this test app - but the difference between JRuby and MRI is about the same as in our real app. I've also only run this on webrick (our real apps run on either unicorn or trinidad depending on ruby vm). The test app can be found here (no need for active_record or any persistence layer to run it): https://github.com/johnae/jruby-view-rendering These are my results when testing in MRI and JRuby: --------------------------------- -- 1.9.3p327 env production -- after 1 request (for "some" warmup - eg. loading code etc) Started GET "/log_entries" for 127.0.0.1 at 2012-11-24 16:01:15 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (19.0ms) Rendered log_entries/index.html.haml within layouts/application (19.4ms) Completed 200 OK in 21ms (Views: 20.3ms) Started GET "/log_entries" for 127.0.0.1 at 2012-11-24 16:01:16 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (19.5ms) Rendered log_entries/index.html.haml within layouts/application (19.8ms) Completed 200 OK in 21ms (Views: 20.7ms) Started GET "/log_entries" for 127.0.0.1 at 2012-11-24 16:01:17 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (19.6ms) Rendered log_entries/index.html.haml within layouts/application (20.1ms) Completed 200 OK in 21ms (Views: 21.1ms) Started GET "/log_entries" for 127.0.0.1 at 2012-11-24 16:01:18 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (28.4ms) Rendered log_entries/index.html.haml within layouts/application (28.7ms) Completed 200 OK in 30ms (Views: 29.6ms) so, MRI completes the request in 20-30 ms. after perhaps 40 requests (MRI shouldn't really need much warmup - but still) Started GET "/log_entries" for 127.0.0.1 at 2012-11-24 16:03:28 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (17.0ms) Rendered log_entries/index.html.haml within layouts/application (17.3ms) Completed 200 OK in 18ms (Views: 18.2ms) Started GET "/log_entries" for 127.0.0.1 at 2012-11-24 16:03:29 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (19.5ms) Rendered log_entries/index.html.haml within layouts/application (19.9ms) Completed 200 OK in 21ms (Views: 20.7ms) Started GET "/log_entries" for 127.0.0.1 at 2012-11-24 16:03:31 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (17.5ms) Rendered log_entries/index.html.haml within layouts/application (17.9ms) Completed 200 OK in 19ms (Views: 18.7ms) Started GET "/log_entries" for 127.0.0.1 at 2012-11-24 16:03:36 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (20.9ms) Rendered log_entries/index.html.haml within layouts/application (21.3ms) Completed 200 OK in 22ms (Views: 22.2ms) so, let's say MRI can complete this request in under 30 ms and usually in around 20 ms. -- jruby 1.7.0 (1.9 mode) env production -- after 1 request (eg. no warmup really, but should still have loaded some stuff) Started GET "/log_entries" for 0:0:0:0:0:0:0:1 at 2012-11-24 15:54:37 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (90.0ms) Rendered log_entries/index.html.haml within layouts/application (91.0ms) Completed 200 OK in 97ms (Views: 96.0ms) Started GET "/log_entries" for 0:0:0:0:0:0:0:1 at 2012-11-24 15:54:38 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (87.0ms) Rendered log_entries/index.html.haml within layouts/application (88.0ms) Completed 200 OK in 95ms (Views: 94.0ms) Started GET "/log_entries" for 0:0:0:0:0:0:0:1 at 2012-11-24 15:54:40 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (74.0ms) Rendered log_entries/index.html.haml within layouts/application (76.0ms) Completed 200 OK in 82ms (Views: 81.0ms) Started GET "/log_entries" for 0:0:0:0:0:0:0:1 at 2012-11-24 15:54:56 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (78.0ms) Rendered log_entries/index.html.haml within layouts/application (80.0ms) Completed 200 OK in 90ms (Views: 89.0ms) so, here it's around 4 times slower than MRI - jruby can complete the request in 82-100 ms after 100 requests (let the jvm warmup some) Started GET "/log_entries" for 0:0:0:0:0:0:0:1 at 2012-11-24 15:56:11 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (37.0ms) Rendered log_entries/index.html.haml within layouts/application (38.0ms) Completed 200 OK in 40ms (Views: 39.0ms) Started GET "/log_entries" for 0:0:0:0:0:0:0:1 at 2012-11-24 15:56:13 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (43.0ms) Rendered log_entries/index.html.haml within layouts/application (44.0ms) Completed 200 OK in 46ms (Views: 46.0ms) Started GET "/log_entries" for 0:0:0:0:0:0:0:1 at 2012-11-24 15:56:14 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (32.0ms) Rendered log_entries/index.html.haml within layouts/application (33.0ms) Completed 200 OK in 36ms (Views: 35.0ms) Started GET "/log_entries" for 0:0:0:0:0:0:0:1 at 2012-11-24 15:56:15 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (44.0ms) Rendered log_entries/index.html.haml within layouts/application (45.0ms) Completed 200 OK in 48ms (Views: 47.0ms) ok, better but still slower than MRI - jruby can now complete the request in around 40-50 ms after 1000 requests (should have warmed up by now) Started GET "/log_entries" for 0:0:0:0:0:0:0:1 at 2012-11-24 15:58:25 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (32.0ms) Rendered log_entries/index.html.haml within layouts/application (32.0ms) Completed 200 OK in 34ms (Views: 34.0ms) Started GET "/log_entries" for 0:0:0:0:0:0:0:1 at 2012-11-24 15:58:26 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (36.0ms) Rendered log_entries/index.html.haml within layouts/application (36.0ms) Completed 200 OK in 38ms (Views: 38.0ms) Started GET "/log_entries" for 0:0:0:0:0:0:0:1 at 2012-11-24 15:58:27 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (32.0ms) Rendered log_entries/index.html.haml within layouts/application (33.0ms) Completed 200 OK in 35ms (Views: 34.0ms) Started GET "/log_entries" for 0:0:0:0:0:0:0:1 at 2012-11-24 15:58:28 +0100 Processing by LogEntriesController#index as */* Rendered log_entries/_table.html.haml (34.0ms) Rendered log_entries/index.html.haml within layouts/application (34.0ms) Completed 200 OK in 37ms (Views: 36.0ms) ok, even better but still slower than MRI, jruby can now complete the request in around 30-40 ms --------------------------------- Now, I know these aren't super-scientific - I've tried to replicate some of the behavior of one of our real apps. The problem is that we see slower view rendering on jruby overall. In general view rendering has been around half as fast in jruby for us and the feel of the app is that it's a bit sluggish compared to before. In development it's slightly worse but doesn't matter as much. My conclusion here is that MRI is faster at completing a request, eg. latency is lower. Best case for JRuby is that it can reach around 58 % of the speed of MRI. The view rendering of the real app is slower than the above (since it's doing more). We see MRI completing requests to the controller/view I've tried to replicate here in around 50-90 ms while JRuby completes them in around 120-180 ms(after warmup). So it seems as if the 58 % of the speed of MRI still holds true. I've really tried everything on JRuby. I tried enabling invokedynamic, tried increasing memory (even tried 2GB where I set xms and xmx both to 2GB). Tried increasing code cache, tried upping permgen. Tried TieredCompilation, tried UseCompressedOops, tried other garbage collectors... Afaik I've exhausted most of the things you CAN do(tried both client and server modes of course - in production we only run the jvm in server mode). I've tried openjdk 7, tried the Oracle JDK 7 (latest as of a week ago). Tried downgrading from jruby 1.7 to 1.6.8, tried upgrading haml to a beta version... even tried this test app in ERB which should be faster (I still see jruby being slower using ERB). So, kind of disappointing results for us. Perhaps I'm missing something but so far JRuby hasn't really been that great for us when running our web apps. The above tests were done on webrick on both MRI and JRuby but in production we run on Trinidad (see the same results there). The other BIG problem we've had is running rake tasks, some of which complete much slower on jruby but they at least do complete... while rake assets:precompile has been... let's say around 100 times slower than MRI - if it completes at all. We were hoping to use less memory on JRuby than on MRI since we run two apps on the same machine(on JRuby they both run in the same JVM) - the end result has been the opposite, especially because of assets:precompile, we sometimes run out of memory running that rake task... something that NEVER happened on MRI. I think we've got ourselves out of the worst of assets:precompile by not using therhubyrhino (which seems to be completely unusably slow) and just using nodejs for assets compilation. It's still much slower than MRI though, and still uses lots more memory than MRI. I really really want to run our web apps on JRuby, but if I can't resolve the above issues I can't really justify it. We still really like the possibilities of JRuby and we've been running our not-a-webapp but a server-app on JRuby since we must have the java integration there + we've been really happy with it's performance. If you have any suggestions - please let me know. Thanks! /John
on 2012-11-24 16:52
on 2012-11-24 19:32
Try running the cpu sampler in visual vm (http://visualvm.java.net) against your app to see what's using up the most time.
on 2012-11-25 13:11
org.jruby.RubyThread.lockInterruptibly is where it's spending 70% of time (cpu time there is 0.000 ms though). Most of the cpu time is spent in org.jruby.util.io.SelectBlob.doSelect(). Not entirely sure how to read the output... I'm not an expert on VisualVM (or the JVM) really. Not seeing haml or anything else showing up at the top.
on 2012-11-25 20:20
John - Firstly, I just want to say, wow, you've been amazingly thorough in pursuing this problem. The dramatic differences you're experiencing between MRI Ruby and JRuby (especially with rake) make me wonder if there's something going on with your Java installation(s). If JRuby were slower at all, I would expect it to be only a little slower, nowhere near your experience. Is there anything you can tell us about the machine on which you're testing (e.g. OS)? Is the total memory enough to support the increased settings you tried? I tried using a ridiculous number, and it didn't complain: >java -Xmx20000000m -jar sample-rails-app.war Also, with whatever memory you have to work with, I'd suggest allocating almost all of it to heap rather than stack. Is it possible that JRuby and/or Java are installed on volumes that are slower than the one on which MRI Ruby is installed? You report similar problems on the production machine; is this the case for both the rails rendering and the rake task? Does the speed difference also occur when running other Ruby apps, subtracting the JVM startup time, in my case, 3.19 seconds: >rvm 1.9 >time ruby -e "" ruby -e "" 0.03s user 0.01s system 8% cpu 0.474 total >rvm jruby >time ruby -e "" ruby -e "" 3.22s user 0.19s system 182% cpu 1.868 total Are you using rvm, by the way? Using SELinux or anything similar that might be inserting itself into the running of the process? Regarding the Rails app benchmark, I don't know how significant, but I wonder if testing the JRuby app on a Java web server would be a fairer comparison than using Webrick on JRuby. Webrick is known to be slow, so running the web server code in Ruby instead of Java may unfairly bias your results. In order to make running a Java web server easy, I tried running warble executable on your project, but when I ran the resulting war file I got this error: >java -jar jruby-view-rendering-master.war Nov 25, 2012 1:34:12 PM winstone.Logger logInternal INFO: Beginning extraction from war file Nov 25, 2012 1:34:17 PM winstone.Logger logInternal WARNING: No webapp classes folder found - /private/var/folders/ll/nyv2lhd08xl8lf0059bmbrw80000gp/T/warbler5205388911019780837webroot/jruby-view-rendering-master.war/WEB-INF/classes Nov 25, 2012 1:34:17 PM winstone.Logger logInternal INFO: Winstone shutdown successfully Nov 25, 2012 1:34:17 PM winstone.Logger logInternal SEVERE: Container startup failed java.lang.ClassCastException: org.jruby.rack.RackFilter cannot be cast to javax.servlet.Filter ... Also, when I tried to run rake assets:precompile in either MRI 1.9.3 or JRuby 1.7, I got: >time rake assets:precompile rake aborted! Don't know how to build task 'assets:precompile' I didn't get either error when using a 'rails new' -ly generated Rails app. I'm not really a Rails developer (yet) though, so I may be missing something simple. Hope you don't mind the stabs in the dark, I'm hoping something might pay off. - Keith --- Keith R. Bennett http://about.me/keithrbennett
on 2012-11-26 09:53
Sure. My development machine is a Macbook Pro Retina Quad-Core Intel Core i7 with 16 GB Ram - OS X 10.8.2. The production machine is an Ubuntu 12.04 7 GB Ram running on EC2 (so - virtualized). I have the same problem in dev as in prod. JRuby is installed on the same volume as MRI. In dev that is a 256 GB SSD, in prod it's an EBS-backed volume. Heh - funny how my development machine is probably faster than my production server. The test app on github isn't for testing assets:precompile (sorry, I might have been unclear) - it's ONLY for the view rendering part. As I said - I'm testing on webrick, but the original concern came from running on either Unicorn or Trinidad (Tomcat wrapped in a bit of ruby). In production we run on Trinidad. It was simply easier to run on webrick since the results were more or less the same as on Trinidad. I've also tested on Torquebox with about the same results - eg. MRI is faster. I'm not using RVM but rbenv in both dev and prod. The slowness (100x slower) running assets:precompile seem to be mostly due to therhubyrhino running completely unoptimized as reported by Charles Nutter here: https://github.com/cowboyd/therubyrhino/issues/23. Of course, one-off commands such as rake will be slower than MRI - but 100x slower while using 10x the ram? That's simply unacceptable. As I said, using nodejs for assets compilation together with turbosprockets-rails ( https://github.com/ndbroadbent/turbo-sprockets-rails3) has made it almost bearable... but compared to MRI it's still like night and day. It's still uses LOTS more memory and is in general... perhaps half as fast, probably slower. So the end result is very mixed. The good stuff is that we get great java integration, pretty awesome deployment possibilities, and a somewhat simpler deployment. The bad stuff is that the app is slower overall (how it "feels"), and I've got the numbers to back that up, the deployment (while simpler) is MUCH slower and uses LOTS more ram. And I've found out the hard way that Trinidad (and, as I've read, other java server containers) leak memory on redeploy so the zero-downtime we've enjoyed on unicorn is a bit less "zero" on JRuby (since a full restart of Trinidad is needed every now and then). Unfortunately, so far, JRuby has meant less good than bad which is the reason we might move back to MRI and Unicorn for the time being... I really WANT to run on JRuby because of it's potential though. I'm not sure if my experiences are because of some bad configuration on my part or if they're something other people are seeing - and I guess I'm interested in the experiences of other people who've moved their Rails apps from MRI to JRuby. Thanks, John
on 2012-11-29 05:03
On Sun, Nov 25, 2012 at 6:10 AM, John Axel Eriksson <john@insane.se> wrote: > org.jruby.RubyThread.lockInterruptibly is where it's spending 70% of time > (cpu time there is 0.000 ms though). Most of the cpu time is spent in > org.jruby.util.io.SelectBlob.doSelect(). > > Not entirely sure how to read the output... I'm not an expert on VisualVM > (or the JVM) really. Not seeing haml or anything else showing up at the top. > > That's just part of the IO subsystem, so I doubt that's what's causing your slowdown. I did some profiling locally to see if I could replicate the behavior you're seeing, but unfortunately, I can't. I did isolate the view rendering in my tests though, so perhaps the issue is just further up your stack. For comparison, here's what I'm seeing (MRI is ruby-1.9.3-p194, JRuby is 1.7.0, JVM is Oracle's 1.7.0_07. I embedded a controller in a benchmark and ran through repeated iterations of rendering the view. 1000 warm-up iterations, then 1000 timed iterations, with results broken into 100 iteration samples. You can see that even after 1000 iterations, the JVM is still optimizing a bit, but by 2000, seems to have reached a steady state. Not sure why it's taking that long to fully optimize, I haven't dug into the numbers further than just doing the sampling, but once it does reach a steady state, JRuby is about 30% faster than MRI. Enabling invokedynamic didn't change performance appreciably, nor did moving the LogEntry.all allocation to either a single-time shared allocation, or a per-render allocation. Either you didn't mention, or I missed it. What JVM are you running on, both in your test environment and production? MRI: [...truncated a bit, since MRI's performance doesn't change much...] Sample mean: 0.044296849999999985; Sample stddev: 0.010034992645606094 Sample mean: 0.043826000000000004; Sample stddev: 0.009419012821220481 Sample mean: 0.043669299999999994; Sample stddev: 0.009377437996539747 Sample mean: 0.043847399999999995; Sample stddev: 0.009612958356192684 Sample mean: 0.044089550000000005; Sample stddev: 0.009703262210395235 JRuby: Sample mean: 0.05607000000000001; Sample stddev: 0.018613699201926466 Sample mean: 0.030839999999999996; Sample stddev: 0.003719237458502387 Sample mean: 0.028590000000000008; Sample stddev: 0.0014361494534084027 Sample mean: 0.02932; Sample stddev: 0.0053689718369403444 Sample mean: 0.028150000000000026; Sample stddev: 0.001479660075623431 Sample mean: 0.028940000000000014; Sample stddev: 0.0026621932174943123 Sample mean: 0.028880000000000013; Sample stddev: 0.004369961745435038 Sample mean: 0.02925000000000002; Sample stddev: 0.0053207711904014535 Sample mean: 0.02742; Sample stddev: 0.0011562740578987733 Sample mean: 0.027309999999999997; Sample stddev: 0.0010019677609281624
on 2012-11-29 08:49
Tested on jruby 1.7.0 and jruby 1.6.8, OpenJDK 7 and Oracle JDK 7. MRI was 1.9.3-p327. I've tested the actual time shown in the rails logs and the time a request takes using curl. In general it's slower on JRuby regardless of JRuby version/JDK version, web server or OS. I see the same thing on webrick as on Trinidad, same thing on Macbook Pro 15 Retina with SSD/Mac OS X 10.8.2 as on Linux Ubuntu 12.04 on EC2/EBS. The "feel" of the app on jruby in both prod/dev is "more sluggish" on JRuby and the numbers back that up. 29 nov 2012 kl. 05:02 skrev Anthony Juckel <ajuckel@gmail.com>:
on 2012-12-05 15:13
Last update on this is that we had to give up. JRuby was simply too slow for us to justify, switching back to MRI was like getting a new server with double everything. It's just ALOT faster. I know this isn't what some benchmarks claim but it's the truth for us. Some things on JRuby are so slow that they're completely, utterly unusable... like rake assets:precompile for example - MRI sometimes takes almost two minutes to compile which to me is unacceptable, JRuby on the other hand can take anywhere from 15 minutes to infinity (eg. I'm not gonna sit around watching it chug away for more than an hour - that process gets killed). We did everything we could to speed up the assets:precompile, for example, not doing all of it - just the parts we needed, switching to nodejs as compiler for the assets, using turbosprockets. All those helped a bit but still unusable i.m.o and much much slower and eating MUCH more memory than MRI(that is compared to MRI without any weird patches to make things go faster). So - deployment of the app wasn't working for us, we must be able to deploy a new version in at most 2-3 minutes (preferrably faster than that). Another issue was the overall sluggishness of the app, it just felt alot slower on JRuby than on MRI. Views rendered in double the time for example. A third issue was the fact that on MRI (just plain old 1.9.3-p125, no patches) we use quite a bit less memory than Trinidad+JRuby. The app on Trinidad leaked memory on every redeploy - something that doesn't happen on unicorn. With unicorn we could do real, zero-downtime deploys. On Trinidad... well, not so much. I didn't dare turning that option on since it leaked ridiculous amounts of memory on "normal" redeploys where requests are paused. The final decision to go back to MRI was made when we tried out JRuby 1.7.1 - for some reason the assets were ALWAYS missing on 1.7.1 (even though we could clearly see them sitting there on disk). For some reason rails+jruby-1.7.1 decided that the hashes of the assets were different from what was on disk. Running assets:precompile a few times (on 1.7.1 - even the full compile without turbosprockets or any other tricks) was useless. Removing all assets and starting from scratch was useless. Our app was just down. We needed to upgrade to 1.7.1 because of https://jira.codehaus.org/browse/JRUBY-7008. Fortunately our first foray into JRuby on Rails was a management app that no customers access - we only use it internally. We wanted to try this app in production first to see what worked and what didn't since this is a low risk app running on only one server. Basically, moving one of our Rails apps to JRuby meant: The bad: Half the performance of MRI rendering views Sluggish "feel" overall Unusable assets precompilation (takes "too long to infinity" on JRuby even with every conceivable tweak or hack to the asset pipeline) Uses a lot more memory than Rails on Unicorn Leaks memory (eg. needs complete Trinidad restart now and then - which means downtime) Frustratingly high memory usage when running command-line tasks (like rake tasks) Frustratingly slow startup - rake tasks aren't much fun (they're slow on MRI too i.m.o but JRuby is like 5x-20x as slow, except for assets compilation which is possibly the worst thing I've ever experienced) Incompatibilities/bugs (yeah well - MRI has bugs too) JRuby 1.7.1 + Rails wouldn't render assets anymore (claimed they didn't exist) The good: Java integration (something we may need) A better concurrency story I'm really sorry that this was our first experience running Rails on JRuby - we really wanted it to work and work faster, deploy easier, be less buggy, have a better concurrency story. None of those (except for maybe concurrency) were true - rather the opposite. Before moving the app to JRuby I had read a few success stories, some of which claimed that view rendering would be faster on JRuby. I did know about slow startup times, but it was in production it that got really frustrating for us. And again - assets:precompile isn't usable on JRuby at all while on MRI it's at best bearable. I wouldn't ever accuse the rails asset pipeline compilation of being fast. I don't want to be too hard on the JRuby devs - I know how much hard work is behind JRuby and I really like the whole idea of running on the JVM (and we still run a non-rails, non-web app on JRuby with success)... I just wanted to let you know that our experience moving a Rails app onto JRuby was far from pleasant. I don't understand how we could have such a bad experience when I've heard so much good about JRuby and JRuby on Rails in talks, on blogs and other places. I also know of several places running JRuby on Rails in production. Either they keep silent about their issues or... I don't know - I'm still open to suggestions and I guess something, somewhere could possibly have been tweaked in some way - though we've been running the app on jruby for three weeks or more in production and I've been tweaking and hacking away quite heavily with mostly nonexistent good results, we've tried OpenJDK 6, OpenJDK 7 and Oracle JDK 7... We were out of ideas and options when we switched back to MRI. Thanks, John
on 2012-12-07 18:25
On 24.11.2012 09:51, John Axel Eriksson wrote: > The other BIG problem we've had is running rake tasks, some of which > complete much > slower on jruby but they at least do complete... while rake > assets:precompile has been... let's say around 100 times slower than > MRI This has been a source of pain for me as well. I did some profiling work, and found much time being spent dealing with exceptions-as-flow-control. This anti-pattern is a performance drain on MRI, but is even more apparent on JRuby. I'd been meaning to come up with a better benchmark for sometime now, and here it is: https://gist.github.com/4234608 https://github.com/pmahoney/assets_comp_perf Still a lot of improvement to be made (though even MRI is painfully slow). I admit I don't quite understand why "assets:precompile" is hardly faster than "assets:clean assets:precompile", so perhaps I don't know enough to even make a proper benchmark... I hope to be able to keep digging into this, but that seems unlikely any time soon. -- Patrick Mahoney
on 2012-12-10 15:02
Hey guys. I just want to pick up this thread again. It has been real interesting to read about the problems people have had with Jruby+Rails and it's looking like it's just not a good fit at all. So is this the general consensus then? That Jruby is not a good fit for rails? Are there alternatives to make the view rendering faster? Has anybody tried using markaby or something similar? Haml? What about the asset pipeline? Any alternatives? What about other frameworks like sinatra? I think for the future googlers we should clean this thread up. Either conclude that jruby should be avoided with rails or find the magic incantation that will make it work. Thanks.
on 2012-12-10 15:44
I'm not knowledgeable about the issues raised in this thread, but I do know that JRuby is used with Rails in production at sites all over. A week or two after giving a JRuby talk at Bangkok's Rails/JavaScript meetup, a European developer told me he switched his business' site to use JRuby and it greatly simplified his operation. He seemed happy with the performance as well. I'm not at all discounting the experiences recounted on this thread, I'm just saying that, based on what I've seen, it would be inaccurate to say that JRuby and Rails do not work well together. It would certainly be nice if one/some of the authors addressed this thread. I did raise the issue with Charlie Nutter when he spoke at Ruby Hangout (on YouTube at https://www.youtube.com/watch?feature=player_embed..., sorry, I don't know where in the video this is), and he acknowledged that there are issues. - Keith --- Keith R. Bennett http://about.me/keithrbennett
on 2012-12-10 16:30
Here's a baseline time for JRuby and assets:precompile for a Rails application with a small to medium amount of assets on my local system: $ time rake RAILS_ENV=production RAILS_GROUPS=assets assets:precompile real 2m22.891s user 4m30.941s sys 0m6.728s There are several options for speeding this up. If your JVM supports it, run JRuby in 32-bit mode - "-J-d32". Try turning off all compilation and running purely interpreted - "-X-C". Combining these options cuts a large percentage of the time off in my tests. $ time JRUBY_OPTS="-J-d32 -X-C" rake RAILS_ENV=production RAILS_GROUPS=assets assets:precompile real 1m41.990s user 1m52.771s sys 0m2.969s If you have the 'node' binary available on your system, you can tell Rails to use that instead of therubyrhino for asset compilation and cut off even more time. $ time EXECJS_RUNTIME='Node' JRUBY_OPTS="-J-d32 -X-C" rake RAILS_ENV=production RAILS_GROUPS=assets assets:precompile real 0m29.981s user 0m32.636s sys 0m2.880s If you don't have the node binary available then you can still gain a large boost by switching from uglifier to closure-compiler for minification by setting config.assets.js_compressor = :closure in config/application.rb. The size of the result assets is almost identical, at least in my case. $ time JRUBY_OPTS="-J-d32 -X-C" rake RAILS_ENV=production RAILS_GROUPS=assets assets:precompile real 0m44.692s user 1m16.724s sys 0m3.262s For reference, Ruby 1.9.3 can compile assets for the above application in 14.314 seconds. With a bit of tweaking I got JRuby from 143 seconds down to 30 seconds. Still not as fast as Ruby 1.9.3, but much closer. Ben
on 2012-12-10 16:56
As someone who uses jruby on rails, but without views, this is really an interesting thread. Could someone put together a simple github repo that reproduces this, with the speed ups? I'd love to see that plus a blog article. Given how prevalent rails is, this seems like an important limitation to make widely known. If only so the next dev knows it's not her fault.
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.