JRuby is a 100% pure-Java implementation of the Ruby programming language.
I have already written about the beauty and power of Ruby and how all smart people should start using it as soon as possible…
In essence, it allows programmers to write programs in Ruby which run on the Java Virtual Machine. The Ruby programming language is better (IMHO) than the Java programming language and, consequently, one can be more productive using Ruby than Java.
For example, this is a small Java program that reads words from the standard input and output the signature of the word (i.e. the letters of the word in sorted order) followed by the word. Cultured readers will recognize an exercise from Programming Pearls by Jon Bentley:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Collections;
import java.util.Vector;
public class Sign
{
public static void main(String[] args)
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String word = null;
try {
word = in.readLine();
}
catch (IOException e) {
System.exit(1);
}
if (word==null) {
break;
}
Vector<Character> letters = new Vector<Character>();
for (int i=0; i<word.length(); i++) {
letters.add(word.charAt(i));
}
Collections.sort(letters);
for (Character letter : letters) {
System.out.print(letter);
}
System.out.println(" " + word);
}
System.exit(0);
}
}
46 lines! Not too bad for Java incidentally. Notice that I’ve used generics that have been introduced in Java recently. The heart of the program reads a word in a string, sends its characters to a vector, sort that vector and, finally, output the letters in sorted order.
The same program in Ruby is:
while word = gets
word.chomp!
letters = word.split("")
letters.sort!
puts letters.join("") + " " + word
end
which is an order of magnitude shorter and clearer (chomp! is used to strip the newline from the end of the word when input).
This program is a normal Ruby program and, hence, using Jruby it can be run atop a JVM. I’ve done some tests on my MacBook on a list of 234,936 English words:
Interpreter | Runtime |
ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-darwin] | 5.702s |
ruby 1.8.5 (2007-06-07 rev 3841) [i386-jruby1.0] | 26.347s |
java version “1.5.0_07” | 19.978s |
From this, I conclude that for small programs, plain Ruby is quicker than anything that run on the JVM (another conclusion is that JRuby’s performance is comparable with Java). This is understandable because the Ruby interpreter is designed for small programs like this. But what about when you have to run a substancial Ruby on Rails application?
According to some important people, this is where JRuby really shines…
JRuby allows Ruby on Rails applications to run on a industrial-grade J2EE application server so much so that people have started predicting the demise of pure Ruby application servers like Mongrel. With the emergence of GlassFish, a free, open source, production-quality, enterprise J2EE application server, it becomes quite reasonable to use the following architecture to deploy easy-to-write yet enterprise-grade web applications:
Exciting times indeed :-)
18 September: an update
Eddy has a much quicker version of my Java program that runs in 4.222s and is therefore quicker than the plain Ruby version and is around 6 times quicker than the JRuby version. Eddy uses toCharArray() instead of sending the individual characters of the String in a Vector.
Thanks!
Post Scriptum
If you read the comments, you’ll see that a number of people are missing the point of this post. Maybe it’s badly written. The point is that Ruby of Rails applications can now run on JRuby which can itself run on GlassFish which is a good thing in my opinion.
eduardo pelegri-llopart says
Hi Avinash – have you seen the GlassFish gem? Check it out at: http://blogs.sun.com/theaquarium/entry/glassfish_gem_for_rails_gf
– eduard/o
Eddy Young says
“Smart people”? “Cultured readers”? What about the rest of us? :-)
Just because I use Java, .NET, and Python, but not Ruby makes me… non-smart? Similarly, because I read Wild Swans, A Million Little Pieces, and The Hidden Connections, but not Programming Pearls, I am… non-cultured? :-P
Maybe it’s just my style, but I find the 17 “actual-code” lines to do the trick just as well, and I’ve got type-checking thrown in the lot to catch errors at compile-time instead of having the code bomb when in production.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
public class Test {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while(true) {
String word = in.readLine();
if (word.trim().length() == 0)
break;
char[] chars = word.trim().toCharArray();
Arrays.sort(chars);
System.out.println(new String(chars) + ” ” + word);
}
}
}
Damn! I’m touchy today *sigh*
Eddy
Eddy Young says
Actually, I would be most interested to see what the benchmark is when a char array is used instead of the vector. Thanks.
Eddy
avinash says
Hi Eddy,
You should read Programming Pearls and have fun with Ruby :-)
Your Java version has a bug and generates a NullPointerException when the last line of the input is read. When the code is corrected (adding if (word==null) break; just after the readline), your program is quicker than the Ruby version. In fact, it runs in 4.222s which is about 5 times better than my Java version.
Congrats :-)
Are there anyone around capable of writing a quicker Ruby (or JRuby) program than what I’ve written?
PS: Thanks Eduardo for the info.
Eddy Young says
Avinash,
Strange– On Windows XP and Java 1.6, null is never read; that’s why I got rid of the if (word == null….
About the performance, actually, I was perplexed that the Ruby version took less time than Java. A major complaint I hear about Ruby is that the performance of the VM is sub-par, hence the hoohas for JRuby and the derived advantage for the faster JVM.
Note: I have nothing against Ruby, but I tend to stick what works best for me and have a dislike techno-missionaries :-)
Yash says
Exactly.
Sun is playing its Enterprise infrastructure card well and we’re now already in the era of Enterprise-level interest and support for Ruby and RoR.
Joao says
Using the Ruby features:
space = ‘ ‘
while word = gets
print word.scan(/./).sort.join, space, word
end
This seems consistently faster for me. :-)
/./ ignores \n by default. To match \n just use the m flag: /./m
avinash says
Fantastic Joao!
Your version runs in only 3.978s. This is the new record :-)
To Eddy:
Personally, I love to tinker with new technologies. That’s part of my job as a lecturer / researcher. I always tell my students that a decent university course should introduce students to technologies that will (might?) become mainstream in the future.
I suppose that students can learn current technologies by themselves using any of those “for dummies” books.
More accurately, universities introduce concepts. And my stand is to introduce new concepts not yet being used in industry like AOP or concurrency. Of course, to learn those new concepts, students should also use the latest technologies not yet being used in industry like AspectJ or Erlang. You see what I mean?
Anyway, can someone write a Java program that’s quicker than Eddy’s version? For the time being, Ruby is quicker (on my MacBook at least)
Eddy Young says
I suppose we could move the “exit” condition into the while (…) statement, like this: while ((word = in.ReadLine()) != null)…, which would eliminate one logical operation. Also, eliminate the .trim(), assuming that there is no trailing spaces as in the Ruby code (or, at least, call it only once).
Next, we could get rid of the String instantiation, as String.out.println will happily take an char[] argument.
Joao–
I would have thought that splitting the word with a regular expression would be more computationally intensive, but it appears not.
Avinash–
I understand your point about the duty of academics to evaluate new technologies, but what I object to is the constant evangelisation (hence, my analogy to missionaries). Academics should present the facts and recommend, not force conversion. Incidentally, the missionary attitude is what I dislike about Torvalds and Stallman despite their accomplishments — one calls C++ programmers “dumb” and the other contradicts his own advocacy of “free software” by trying to push people in one direction without regard to freedom of choice.
Eddy Young says
Can you please make the comment text-box a tad wider and taller? It’s a pain revising what has been typed in such a small space — although I could resize it at will if I was using Safari 3.
Spacebat says
Pardon the golf, but here’s the same thing in Perl:
while (<>) {
chomp;
print join(“”, sort split “”), ” $_\n”;
}
Spacebat says
while (<>) {
print join(“”, sort /(.)/g), ” $_\n”;
}
*hangs head in shame*
eduardo pelegri-llopart says
re: performance — there is also the JVM start-up time. It has improved substantially in JDK6 but it still is non-trivial. – eduard/o
avinash says
Hi Spacebat,
Your perl program has a small bug which is easy to correct (replace ” $_\n” by ” $_”)
It runs in 2.573s but that does not count as it is written in Perl :-) I guess plain C will give the best performance…
To Eduardo:
Of course. Loading the JVM is bound to take some time. That’s why I’ve repeated the test 2-3 times and hope that caching (I have 2Gb) will partly take care of that.
To all:
Remember that we are not trying to prove that Ruby is slow. We already know that. And we all know that JRuby is slower still. The point is JRuby allows running Ruby on Rails apps on an industrial grade J2EE application server… :-)
avinash says
Incidentally Eddy, concerning:
“Academics should present the facts and recommend, not force conversion.”
I am 100% with you on this. Students should choose by themselves what to use. The pre-requisite, of course, is to expose them to many different things. I love Joel Spolsky’s The Perils of Java Schools…
Eddy Young says
You’re right. Some of my colleagues don’t know that there is such a thing as a quick-sort.
I also have to admit that having forgotten the algorithm after 15+ years of relying on the likes of Arrays.sort() :-) But, at least, having had exposure to those algorithms, if I had to re-implement a sort funtion, I would know to type “quick sort” in Google!
Javed Mandary says
Hi,
I agree that ruby rocks..although I haven’t played with JRuby but I have been fooling around with Ruby on Rails (RoR) and it is simply pure joy to work with it ..imagine making a blog application in 15 minutes .. yes 15 minutes!
However I believe that Ruby could be a PHP replacement but not yet mature to work against J2EE applications simplier because it cannot scale… but given the interest that developers are giving to it these days..you never know.
Joao says
Here’s how Perlish Ruby gets:
space = ‘ ‘
while gets
print $_.scan(/./).sort.join, space, $_
end
:-)
I have been using Mongrel in conjunction with Nginx, and they together make a hell of a combination for me. The main advantage to using GlassFish would be to avoid using two web servers and perhaps multiple instances of Mongrel to make the server handle a greater load. I don’t use Rails though, but my own framework which I am happy with. I tested JRuby in the past and I hope it will keep on improving. Make no mistake, JRuby has a lot of incentive to improve, because Ruby is very good and lightweight so the competition is fierce. I just tested a new version of Ruby’s next version and I could notice some huge improvements, with some smart optimizations and new features (multilingualization as Matz calls it which has just been checked in trunk, ready for the Xmas release of Ruby).
selven says
Thank god am no more planning a career in a crazy field like that! Fighting over whose language is better is like fighting over who’s got the better car! language over language, re-inventing the wheel everytime, and spending lots of valuable time in just learning the language, rather than just learn one language, build on it layer by layer, improving that one language and start building things rather than continuously learning every new language out there as if to collection stuff to write on a cv. Probablement si mo ti rich and own a business, mo ti pou prend zis ppl who know one thing but good at it, and just spend more and more to reach the limit of that!
+selven
Yash says
Both for business and academia, I would recommend Ruby. In the first case, it is not a silver bullet but the object-orientation principles are well implemented in the language.
In the second case, it’s a simple, readable language which can be used in an OO way or in a traditional and simple way. It’s great for learning programming.
@Eddy: you are quite mistaken about Stallman and Torvalds. Both are very vocal and influential but neither of them forces you to lose your freedom of choice.
On the contrary, Stallman wants you to have an avenue of getting and preserving computing freedoms.
In the grand scheme of things, you are still free to choose completely closed systems and languages which make you unproductive.
I believe the evangelism isn’t the real issue here (you do the same with Java, isn’t it?), but rather the ‘pain’ of learning new things or seeing that a new trend emerges. But it’s necessary to follow what is happening, as there are very valid and very important reasons for these effects.
Java is great as a platform and as a VM, but the language and frameworks for development make you less productive than Ruby and Ruby on Rails. There are specific reasons for that.
It’s important to listen to those ‘techno-missionaries’ from time to time.
Yash says
@Javed: “Ruby…PHP…J2EE application…as it cannot scale”
If you’re talking about apps built with the RoR framework, you’re wrong about the scaling. The architecture makes it subject to the same decisions you’d use to make a PHP app scale.
The next iteration of Ruby will include the faster Yarv VM. Ruby will be faster, and thus RoR too.
selven says
you are still free to choose completely closed systems and languages which make you unproductive.
its not proven that closed systems makes you unproductive, there are certain cases where closed systems would be beneficial
Joao says
For the sake of creating teaching documentation, here’s a two lines Ruby solution:
space = ‘ ‘
print $_.scan(/./).sort.join, space, $_ while gets
Joao says
It could be one line as well:
print $_.scan(/./).sort.join, ‘ ‘, $_ while gets
:-)
Cheers!
Eddy Young says
Yash–
Where have I ever evangelised Java? The closest I’ve come to evangelising something is by writing a personal experience with the RIFE framework. Otherwise, I’ve shown how to do things in Java, .NET, PHP, Python, and C++ on my blogs without once telling that one language should be used over the rest.
Regarding Torvalds, whatever respect I had for him went out of the window by his opening statement to a poster’s comment — nothing should warrant such a harsh reply. See http://thread.gmane.org/gmane.comp.version-control.git/57643/focus=57918
Oh, I do follow trends, but not blindly. I keep an eye on those technologies that are useful to me in my line of work. If my employer decided to go with RoR tomorrow morning, I’ll probably be productive by the afternoon. I don’t have any problem learning new languages and frameworks. As for listening to techno-missionaries, thanks but no thanks. I can read and take my own decisions; I don’t need evangelisation to be convinced.
For an enterprise, producing code in quick turn-around is not as important as having a solid framework based on a proven platform with a clear roadmap that spans the enterprise’s own. At the moment, Java and .NET have that, but not RoR unfortunately. When that happens, I’m sure we won’t hesitate to make the move.
Eddy Young says
BTW, closed systems do not necessarily equate to reduced productivity. At work, we always hit the mark with our four-week release cycles to the great satisfaction of our customers. And, we’re using Microsoft’s own .NET and our own programming language.
selven says
For an enterprise, producing code in quick turn-around is not as important as having a solid framework based on a proven platform with a clear roadmap that spans the enterprise’s own. At the moment, Java and .NET have that, but not RoR unfortunately. When that happens, I’m sure we won’t hesitate to make the move.
Well said Eddy, a realistic comment!
avinash says
Yes.
And that’s why it’s very interesting that RoR applications can now run on J2EE.
Eddy Young says
No, J2EE has a roadmap. RoR does not yet have a convincing roadmap.
But I agree support for RoR on J2EE is a good start.
afsina says
God.. when did you learn Java. this was a horrible code example.
whoa says
this was the lamest benchmark i have ever seen.
first, the java code is written by an idiot.
Code can easily be like this:
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String word;
while ((word = in.readLine()) != null) {
char[] chars = word.toCharArray();
Arrays.sort(chars);
System.out.println(new String(chars));
}
}
Second, everybody knows ruby sucks ass in terms of performance. check the language shhotout. most algorithms it is 100 to 500 times slower then java. what a BS.
ahmetaa says
i agree that given java code is very very poor. i actually tried the code you have written with the version written by the commenter. Here is the facts:
– the version you wrote (or quoted) is around 10 times slower then the short version.
– you gave wrong line counts. the original line count is (without spaces, including unnecessary closing brackets and imports.) 33, not 46. the shorter version, again shorter version is 15 lines (including imports, closing brackets etc.)
– In the code, most time is lost during the printing. in fact, if you do not write the print out, algorithms are around 10 times faster. Which concludes, possibly the shorter version, without printing would be 30-40 times faster then the ruby version.. try it if you want.
it is obvious that java is not proper for some script needs . but it is extremely fast comparing with current scripting languages. if you modularize your code, this line counts would also stop making any sense. please get your facts right next time. i will make a blog entry about this too.
avinash says
To afsina & whoa:
If you read the post carefully, you’ll realize that it was not supposed to be a benchmark (the title is ‘the significance of JRuby and Glassfish’ and not ‘Java is bad’).
Saying that the code is ‘horrible’ is a little excessive. It is not quick but it works. And it is clear enough. If you think about it, the compiler should have warned me that there is a better way to do what I was trying to do. Or better yet, use the best construct automatically :-)
On the other hand, calling me an idiot is idiotic.
Thanks to Eddy nevertheless for introducing me (us?) to the quick toCharArray() method.
To Ahmetaa:
Thanks for trying out both versions but I guess you are missing the point of the post. Maybe I was not clear enough. I repeat, the title is ‘The significance of JRuby and Glassfish’…
To all:
I like Java. It’s a nice programming language. But some people might not like it because liking something is subjective. I would advise those people to explore alternative programming languages and frameworks running on top of the JVM (like Bistro, Groovy, Jatha, Jython, JRuby, Nice, Rhino, Scala, SISC, etc).
In the real world, different people express themselves differently and like different things :-)
Yash says
@Eddy: “For an enterprise, producing code in quick turn-around is not as important as having a solid framework based on a proven platform with a clear roadmap that spans the enterprise’s own.”
No, the best enterprises always have R&D and pilot projects and teams working on how to improve their business processes.
This is why IBM, Accenture, SUN, Apple and others are already involved with RoR.
The nature of business and IT is change and adaptability.
And since IT is integrated with Business Processes nowadays, the enterprises with the edge in IT are the more competitive.
That entails listening to those who are visionaries.
Yash says
By the way:
@ Selven and @Eddy – the “which make you unproductive” in my sentence referred to languages.
But you could also make the point for some closed operating systems, especially if you’ve seen the complaints of people who code in Javascript.
Eddy Young says
Yash,
My point is, many enterprises are not convinced that there is a clear roadmap for RoR at this point, so they run high risks by basing their products on it.
As for IBM and co getting involved with RoR, this is a common strategy. The aim is to keep the project alive and align its roadmap to their own. IBM did the same with Linux, and Microsoft is doing it with Novell/Mono.
For companies that do not have the resources to ensure the survive-ability of a technology (either by contributing to it themselves or pay others to), there is just too much risk.
Honestly, if you were not sure RoR would still be around in X years, would you build a product on it?
— Eddy
Kailash says
Am mistaken or is Avinash’s blog more active than LUGM’s mailing list?
Jeshan says
@Avinash:
I know that the point of this post is about JRuby/Glassfish, but i could not believe that we need 46 lines to do just that!
What do you think of this?
import java.io.Console;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Console console = System.console();
while (true) {
String line = console.readLine().trim();
if (line == null)
break;
char[] array;
Arrays.sort(array = line.toCharArray());
System.out.println(new String(array).trim() + ” ” + line);
}
}
}
It’s not that verbose after all…
Please tell us about the test results.
Note: requires jdk 1.6
Anonymous says
Ruby is aswell chargeless of charge. It is aswell chargeless to copy, use, modify, and distribute. Since Ruby can be modified, programmers can accomplish all-important changes and can code after activity restricted.