Forum: JRuby Compile and execute ruby script at runtime?

Posted by DG Christensen (Guest)
on 2012-10-18 19:36
(Received via mailing list)
Hello,

I have written a DSL using Ruby that I run on my JBoss server(s).
Currently I load a ScriptEngine using "JRuby" and execute the script
(which is stored in the DB).  This is running horribly slow and I'm
looking at ways to improve it.  The Ruby script calls Java and it looks
like the Ruby->Java interface is really slow when running via 
ScriptEngine.

One thing I'm considering is compiling the script at runtime and
executing the resulting code directly; this allows me to remove
ScriptEngine altogether.  Is this possible?  I'd rather not compile all
the scripts pre-runtime because that prevents me from updating the
scripts (in the DB) and reloading them on the server without restarting
the server.

Thanks
Posted by Keith B. (keith_b)
on 2012-10-18 22:00
(Received via mailing list)
DG -

Can you be more specific as to exactly what is slow?  Are you sure it's 
the JRuby interpretation of the code?  Can you tell us more about what 
the code's doing, and what kind of Ruby <--> Java interop there is?  Is 
it calling something in Java many times?  Etc...

In case you're not already familiar with it, Ruby's benchmarking is 
helpful and very easy to use (see 
http://www.ruby-doc.org/stdlib-1.9.3/libdoc/benchm...).

- Keith
Posted by DG Christensen (Guest)
on 2012-10-19 01:00
(Received via mailing list)
Thanks for your response Keith.

I don't have any hard data to show you, unfortunately.  My DSL is
basically a ruby wrapper around Java classes and most of the work is
done in Java.  When I first started I had a lot of loops written in Ruby
that called Java inside the loop.  At this time my Ruby scripts were
taking 10-12 seconds to run.  My first optimization was to write helper
methods in Java that performed the loops, which were called from Ruby.
I.e. same amount of work in the end but a lot fewer Ruby->Java calls.
This cut the runtime down by about half but still not good enough.

My latest optimization was to precompile the scripts into Java objects
as detailed here:
https://github.com/jruby/jruby/wiki/DirectJRubyEmbedding.  I also set
the JRuby JIT threshold to 0.  The objects are then cached for later
use.  This got my execute time down to under a second which is good
enough for now.
Posted by Charles Nutter (headius)
on 2012-10-27 08:43
(Received via mailing list)
On Thu, Oct 18, 2012 at 12:33 PM, DG Christensen <dgc@enservio.com> 
wrote:
> I have written a DSL using Ruby that I run on my JBoss server(s).
> Currently I load a ScriptEngine using "JRuby" and execute the script
> (which is stored in the DB).  This is running horribly slow and I'm
> looking at ways to improve it.  The Ruby script calls Java and it looks
> like the Ruby->Java interface is really slow when running via ScriptEngine.

Under some modes in some versions of JRuby, ScriptEngine will disable
our internal JIT compilation. That may be why things are slower than
you expect.

> One thing I'm considering is compiling the script at runtime and
> executing the resulting code directly; this allows me to remove
> ScriptEngine altogether.  Is this possible?  I'd rather not compile all
> the scripts pre-runtime because that prevents me from updating the
> scripts (in the DB) and reloading them on the server without restarting
> the server.

That's certainly an option. There are a few articles on the wiki about
generating "normal" Java classes you can call directly as long as
JRuby's present in classpath.

- Charlie
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
No account? Register here.