Getting back into indy...need a better argument collector!
Paul Sandoz
paul.sandoz at oracle.com
Fri Mar 26 16:20:11 UTC 2021
Hi Charlie,
Thanks for the details. I quickly logged:
https://bugs.openjdk.java.net/browse/JDK-8264288
I don’t have time to dive into the details right now. Perhaps next week, or hopefully someone else can.
Paul.
> On Mar 25, 2021, at 9:25 PM, Charles Oliver Nutter <headius at headius.com> wrote:
>
> JRuby branch with changes to use our own collector methods:
> https://github.com/jruby/jruby/pull/6630
>
> InvokeBinder 1.2 added collect(index, type, collector) that calls
> MethodHandles.collectArguments:
> https://github.com/headius/invokebinder/commit/9650de07715c6e15a8ca4029c40ea5ede9d5c4c9
>
> A build of JRuby from the branch (or from jruby-9.2 branch or master
> once it is merged) compared with JRuby 9.2.16.0 should show the issue.
> Benchmark included in the PR above.
>
> On Thu, Mar 25, 2021 at 8:43 PM Charles Oliver Nutter
> <headius at headius.com> wrote:
>>
>> After experimenting with MethodHandles.collectArguments (given a
>> hand-written collector function) versus my own logic (using folds and
>> permutes to call my collector), I can confirm that both are roughly
>> equivalent and better than MethodHandle.asCollector.
>>
>> The benchmark linked below calls a lightweight core Ruby method
>> (Array#dig) that only accepts an IRubyObject[] (so all arities must
>> box). The performance of collectArguments is substantially better than
>> asCollector.
>>
>> https://gist.github.com/headius/28343b8c393e76c717314af57089848d
>>
>> I do not believe this should be so. The logic for asCollector should
>> be able to gather up Object subtypes into an Object[] subtype without
>> an intermediate array or extra copying.
>>
>> On Thu, Mar 25, 2021 at 7:39 PM Charles Oliver Nutter
>> <headius at headius.com> wrote:
>>>
>>> Well it only took me five years to circle back to this but I can
>>> confirm it is just as bad now as it ever was. And it is definitely due
>>> to collecting a single type.
>>>
>>> I will provide whatever folks need to investigate but it is pretty
>>> straightforward. When asking for asCollector of a non-Object[] type,
>>> the implementation will first gather arguments into an Object[], and
>>> then create a copy of that array as the correct type. So two arrays
>>> are created, values are copied twice.
>>>
>>> I can see this quite clearly in the assembly after letting things
>>> optimize. A new Object[] is created and populated, and then a second
>>> array of the correct type is created followed by an arraycopy
>>> operation.
>>>
>>> I am once again backing off using asCollector directly to instead
>>> provide my own array-construction collector.
>>>
>>> Should be easy to reproduce the perf issues simply by doing an
>>> asCollector that results in some subtype of Object[].
>>>
>>> On Thu, Jan 14, 2016 at 8:18 PM Charles Oliver Nutter
>>> <headius at headius.com> wrote:
>>>>
>>>> Thanks Duncan. I will try to look under the covers this evening.
>>>>
>>>> - Charlie (mobile)
>>>>
>>>> On Jan 14, 2016 14:39, "MacGregor, Duncan (GE Energy Management)" <duncan.macgregor at ge.com> wrote:
>>>>>
>>>>> On 11/01/2016, 11:27, "mlvm-dev on behalf of MacGregor, Duncan (GE Energy
>>>>> Management)" <mlvm-dev-bounces at openjdk.java.net on behalf of
>>>>> duncan.macgregor at ge.com> wrote:
>>>>>
>>>>>> On 11/01/2016, 03:16, "mlvm-dev on behalf of Charles Oliver Nutter"
>>>>>> <mlvm-dev-bounces at openjdk.java.net on behalf of headius at headius.com>
>>>>>> wrote:
>>>>>> ...
>>>>>>> With asCollector: 16-17s per iteration
>>>>>>>
>>>>>>> With hand-written array construction: 7-8s per iteration
>>>>>>>
>>>>>>> A sampling profile only shows my Ruby code as the top items, and an
>>>>>>> allocation trace shows Object[] as the number one object being
>>>>>>> created...not IRubyObject[]. Could that be the reason it's slower?
>>>>>>> Some type trickery messing with optimization?
>>>>>>>
>>>>>>> This is very unfortunate because there's no other general-purpose way
>>>>>>> to collect arguments in a handle chain.
>>>>>>
>>>>>> I haven¹t done any comparative benchmarks in that area for a while, but
>>>>>> collecting a single argument is a pretty common pattern in the Magik code,
>>>>>> and I had not seen any substantial difference when we last touched that
>>>>>> area. However we are collecting to plain Object[] so it might be that is
>>>>>> the reason for the difference. If I¹ve got time later this week I¹ll do
>>>>>> some experimenting and check what the current situation is.
>>>>>
>>>>> Okay, I’ve now had a chance to try this in with our language benchmarks
>>>>> and can’t see any significant difference between a hand crafted method and
>>>>> asCOllector, but we are dealing with Object and Object[], so it might be
>>>>> something to do with additional casting.
>>>>>
>>>>> Duncan.
>>>>>
>>>>> _______________________________________________
>>>>> 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
> https://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
More information about the mlvm-dev
mailing list