AOT Compilation of Ruby Libraries

Does the AOT compiler produces class files that are usable not just as
standalone scripts, but also to be loaded into a JRuby interpreter?
(i.e.,
require ‘foo.rb’ will load ‘foo.class’)

My app uses a few Ruby libraries, and I have been concerned about the
launch
time, which seems to be dominated by the parser (I haven’t profiled yet
though, but it took a while before my user code starts to run). Would it
be
possible to AOT compile all the ruby libraries (e.g. ActiveRecord,
ActiveSupport, etc) and package them in a JAR? Would this produce any
speedup
in the load time?

I know that there has been a recent speedup in launch time of JRuby, by
including the JAR in the bootstrap classpath, but due to my project
requirement, I can’t put things in the bootstrap classpath. I am hoping
that
the AOT compiler may help though.

Peter


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

If you say require ‘foo’ then JRuby will pick up either a .rb file or
a .class file of the name. (Sorry, I don’t remember off the top of my
head which it prefers) I have been using this feature for months so
that my application can be run from the filesystem (.rb files I’m
working on in development) or from a single jar file file (when
actually used by the customer).

On Jun 26, 2008, at 4:35 AM, Peter K Chan wrote:

Would it be
the AOT compiler may help though.

Peter


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

I did not notice anything, but:

  1. The project size is about 76 small classes + JRuby complete. There
    isn’t anything hefty like a frozen rails.
  2. I did no performance checking either before or after switching over
    to compiling the classes. It isn’t a concern for me in this project.

On Jun 26, 2008, at 12:54 PM, Peter K Chan wrote:

Matt,
That’s great to know. My app has the exact settings as you (i.e.
develop with unpacked .rb, deployed with all-in-one-JAR).

Out of curiosity, did you notice any performance speedup associated
with the AOT compilation and lack of parsing?

Peter


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Matt,
That’s great to know. My app has the exact settings as you (i.e.
develop with unpacked .rb, deployed with all-in-one-JAR).

Out of curiosity, did you notice any performance speedup associated
with the AOT compilation and lack of parsing?

Peter

I have just gotten the AOT to run with my project, with minimal change,
which
is impressive and very seamless. However, I did notice a few issues:

  • When loading file name with dashes in it, the interpreter does not
    load the
    proper escaped name (i.e. compiler produces rexml/encodings/UTF_minus_8
    for
    rexml/encodings/UTF-8, but interpreter still only loads
    rexml/encodings/UTF-8). I will file a bug for this.

  • The compiler default is to place everything under the “ruby” prefix,
    but the
    interpreter does not “prefix” with ruby when loading (which makes sense,
    but
    is not mentioned anywhere). The solution is to explicitly tell the
    compiler to
    use empty prefix (-p “”).

  • It would be nice if the interpreter can automatically load “foo.class”
    when
    asked to load “./foo.rb”.

  • My project uses a few big Ruby libraries (ActiveRecord, ActiveSupport,
    etc),
    with 1500+ files. The launch time went from 3s to 11s. I am not sure why
    AOT
    is so much slower than purely interpreted. This is a disappointment, as
    I was
    hoping that the AOT compilation would speed ruby loading, but instead it
    slowed down by four times.

Peter

Peter K Chan wrote:

I have just gotten the AOT to run with my project, with minimal change, which
is impressive and very seamless. However, I did notice a few issues:

In general the compiler has developed entirely based on feedback and
ideas. So please, please, everyone that uses the compiler: share your
thoughts for making it better and more rubyish. And since the logic for
reading in the file(s) and dumping classfile(s) to disk is largely
contained in the jrubyc script + lib (all Ruby code) perhaps patches or
improvements could come with your ideas.

  • When loading file name with dashes in it, the interpreter does not load the
    proper escaped name (i.e. compiler produces rexml/encodings/UTF_minus_8 for
    rexml/encodings/UTF-8, but interpreter still only loads
    rexml/encodings/UTF-8). I will file a bug for this.

Ahh yes, I remember I wanted to fix this and never got around to it.

  • The compiler default is to place everything under the “ruby” prefix, but the
    interpreter does not “prefix” with ruby when loading (which makes sense, but
    is not mentioned anywhere). The solution is to explicitly tell the compiler to
    use empty prefix (-p “”).

I’m still on the fence about the compiler prefix. I added it to help
offset compiled .rb code from the normal Java package space, and to
avoid cases where the leading element of the Ruby dir might not be legal
as a root package (like if someone compiled java/foo/bar.rb).

For the most part this is a feature that was added in a vacuum, based
solely on a few technical challenges I ran into. If it seems too
cumbersome, I’m open to suggestions.

  • It would be nice if the interpreter can automatically load “foo.class” when
    asked to load “./foo.rb”.

If you’re referring to “load ‘./foo.rb’” in Ruby code, this is largely
correct load behavior. load requires you to specify exactly the filename
you want it to load. However, I can understand the desire to precompile
and still have load ‘xxx.rb’ continue to work. I’d like to make an
exception, but it would mean modifying load to have extension-swapping
logic. Worth it?

  • My project uses a few big Ruby libraries (ActiveRecord, ActiveSupport, etc),
    with 1500+ files. The launch time went from 3s to 11s. I am not sure why AOT
    is so much slower than purely interpreted. This is a disappointment, as I was
    hoping that the AOT compilation would speed ruby loading, but instead it
    slowed down by four times.

There are two reasons for this:

  • Classloading and verification appear to actually be slower than
    parsing .rb source.
  • We’ve done little work to investigate why compiled Ruby code loads
    slower, so there certainly could be specific bottlenecks or logic that
    could be made lazy.

I’d like to be able to say that precompiled code loads faster some day,
so perhaps file a bug for the slow load time. A few examples would be
helpful too, like maybe a benchmark that creates, compiles, and then
benchmarks loading 1000 files? And then different runs that vary size
and complexity?

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Matt Fletcher wrote:

When I first converted my project over from jarring .rb files into
jarring .class files, it was easiest to use an empty prefix. So yeah,
that feature got in my way as well – it took me a little while to
figure out what the hell was wrong. But now I’ve changed my project to
actually apply a real, Java-ish prefix to my Ruby files, so this feature
is invaluable.

My suggestion would be to change the default behavior to not
automatically apply a prefix. But please don’t remove the feature. :slight_smile:

Hmm, noted. I’m kinda leaning this way myself, since the automatic
“ruby” prefix means in-place compiling doesn’t work without additional
flags. That’s not very convention-over-configuration.

Could one of you file a bug for this?

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On Fri, Jun 27, 2008 at 6:01 PM, Charles Oliver N.
[email protected] wrote:

Hmm, noted. I’m kinda leaning this way myself, since the automatic “ruby”
prefix means in-place compiling doesn’t work without additional flags.
That’s not very convention-over-configuration.

Also, some time in the past I spent at least a couple of hours on
Windows trying to fix one of our tests that was using jrubyc and
needed no prefix, and quoting/escaping jrubyc --prefix “” was not
fun. :slight_smile:

–Vladimir


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Matt captured my sentiment about the feature too. I found the compiler
to work very well, except for the default prefix. JIRA issue has been
filed for this.

Going back to the performance of AOT compilation. I did turn off
verification with -Xverify:none, so the overhead shouldn’t come from
verification. A few thousand classes also shouldn’t take this long to
load. Could this have something to do with the one-classloader-per-file
feature that I have heard about? If a classloader is created for every
foo.class, I can see why it may slow down. I haven’t had the time to
drill down to a generic test case, but I will file a JIRA to aid the
discussion.

Also, I think it would be worth it to load ‘foo.class’ when requiring
‘./foo.rb’, but only in the case of loading compiled file. I think it’s
straightforward to put the prefix-elimination logic in, since we are
already automatically loading the .class file when asking for .rb with
the current runtime. (when you are automatically loading .class, the
concept of ./foo.class doesn’t make sense anyway).

Peter

Oh yeah, I ran into this as well and it kinda screwed up my upgrade
path from 1.1RC2 to 1.1.2 this week. Blech.

On Jun 27, 2008, at 12:30 PM, Vladimir S. wrote:

needed no prefix, and quoting/escaping jrubyc --prefix “” was not
fun. :slight_smile:

–Vladimir


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

FYI, I just committed a change so the default is no prefix. I agree it’s
better this way.

Matt Fletcher wrote:

That’s not very convention-over-configuration.


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On Jun 26, 2008, at 7:56 PM, Charles Oliver N. wrote:

In general the compiler has developed entirely based on feedback and
ideas. So please, please, everyone that uses the compiler: share
your thoughts for making it better and more rubyish. And since the
logic for reading in the file(s) and dumping classfile(s) to disk is
largely contained in the jrubyc script + lib (all Ruby code) perhaps
patches or improvements could come with your ideas.

For what it’s worth, the compiler as you developed it has satisfied my
needs quite nicely. I’ve run into a couple of bugs related to loading
and using .class files, but other than that it’s been working great.

I’m still on the fence about the compiler prefix. I added it to help
offset compiled .rb code from the normal Java package space, and to
avoid cases where the leading element of the Ruby dir might not be
legal as a root package (like if someone compiled java/foo/bar.rb).

For the most part this is a feature that was added in a vacuum,
based solely on a few technical challenges I ran into. If it seems
too cumbersome, I’m open to suggestions.

When I first converted my project over from jarring .rb files into
jarring .class files, it was easiest to use an empty prefix. So yeah,
that feature got in my way as well – it took me a little while to
figure out what the hell was wrong. But now I’ve changed my project to
actually apply a real, Java-ish prefix to my Ruby files, so this
feature is invaluable.

My suggestion would be to change the default behavior to not
automatically apply a prefix. But please don’t remove the feature. :slight_smile:


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email