JRuby to Java invokedynamic dispatch

Charles Oliver Nutter headius at headius.com
Thu Jun 9 12:09:31 PDT 2011


Not to temper your enthusiasm, but the obvious answer here is that the
perf gains are largely from avoiding a reflective invocation. To me
that doesn't make the results any less spectacular, since they were
far easier to wire in than hand-generated stubs (which Groovy does and
which JRuby can do if you specify a property).

It's a very exciting time to be on the JVM :)

- Charlie

On Thu, Jun 9, 2011 at 12:18 PM, Christian Thalinger
<christian.thalinger at oracle.com> wrote:
> On Jun 8, 2011, at 11:10 PM, Attila Szegedi wrote:
>> Woo-hoo!
>
> I agree :-)
>
>>
>> On Jun 8, 2011, at 9:48 PM, Charles Oliver Nutter wrote:
>>
>>> Hello friends! I have another update!
>>>
>>> I've just landed preliminary work to make JRuby directly bind Ruby to
>>> Java calls that were normally done via reflection! Currently only
>>> no-arg methods that return primitives, CharSequence/String, or void
>>> get patched straight through, but in those cases it makes a solid
>>> performance difference.
>>>
>>> Here's two benchmarks before direct binding and after:
>>>
>>> BEFORE (using invokedynamic, but bound to a DynamicMethod wrapper
>>> around java.lang.reflect.Method
>>>
>>> Measure System.currentTimeMillis, long becoming Fixnum
>>> 0.277000   0.000000   0.277000 (  0.278000)
>>> 0.188000   0.000000   0.188000 (  0.188000)
>>> 0.191000   0.000000   0.191000 (  0.191000)
>>> 0.221000   0.000000   0.221000 (  0.221000)
>>> 0.198000   0.000000   0.198000 (  0.199000)
>>> Measure java.lang.Thread#name, String entering Ruby
>>> 0.520000   0.000000   0.520000 (  0.520000)
>>> 0.380000   0.000000   0.380000 (  0.380000)
>>> 0.383000   0.000000   0.383000 (  0.383000)
>>> 0.378000   0.000000   0.378000 (  0.378000)
>>> 0.388000   0.000000   0.388000 (  0.389000)
>>>
>>> AFTER (using invokedynamic and MHs all the way to the target)
>>>
>>> Measure System.currentTimeMillis, int becoming Fixnum
>>> 0.173000   0.000000   0.173000 (  0.172000)
>>> 0.126000   0.000000   0.126000 (  0.126000)
>>> 0.137000   0.000000   0.137000 (  0.137000)
>>> 0.148000   0.000000   0.148000 (  0.148000)
>>> 0.147000   0.000000   0.147000 (  0.147000)
>>> Measure java.lang.Thread#name, String entering Ruby
>>> 0.521000   0.000000   0.521000 (  0.521000)
>>> 0.276000   0.000000   0.276000 (  0.276000)
>>> 0.274000   0.000000   0.274000 (  0.274000)
>>> 0.274000   0.000000   0.274000 (  0.274000)
>>> 0.276000   0.000000   0.276000 (  0.276000)
>>>
>>> In the latter case, this is only a tiny bit slower than a JRuby core
>>> class method that constructs a Ruby String, so the dispatch overhead
>>> of Ruby to Java has almost completely disappeared! Amazing!
>>>
>>> This can be disabled with jruby.invokedynamic.java=false, but since
>>> it's showing such a good perf improvement I've got it on by default
>>> right now.
>>>
>>> - Charlie
>>> _______________________________________________
>>> mlvm-dev mailing list
>>> mlvm-dev at openjdk.java.net
>>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>>
>> _______________________________________________
>> mlvm-dev mailing list
>> mlvm-dev at openjdk.java.net
>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>
>
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>


More information about the mlvm-dev mailing list