RFR(s): 8078463: optimize java/util/Map/Collisions.java
Martin Buchholz
martinrb at google.com
Fri May 15 20:42:55 UTC 2015
Go ahead and push.
(Optimizing test runs is pretty important long term)
On Thu, May 14, 2015 at 1:47 PM, Stuart Marks <stuart.marks at oracle.com>
wrote:
> On 5/14/15 1:22 AM, Daniel Fuchs wrote:
>
>> I'm curious: have you tried with using a lambda instead? changing:
>>
>> 394 static void check(String desc, boolean cond) {
>> 395 if (cond) {
>> 396 pass();
>> 397 } else {
>> 398 fail(desc);
>> 399 }
>> 400 }
>>
>> into
>>
>> static void check(Supplier<String> descSupplier, boolean cond) {
>> if (cond) {
>> pass();
>> } else {
>> fail(descSupplier.get())
>> }
>> }
>>
>> I wonder how the performance would compare...
>>
>
> I hadn't tried this, but I did out of curiosity. It's not very good. Here
> are the numbers:
>
> (current jdk9-dev, -Xcomp -XX:+DeoptimizeALot -client, 3GHz i7, MBP 13"
> 2014, elapsed time in seconds, averaged over five runs)
>
> 21.4 original
> 18.7 lambda
> 14.2 varargs
> 12.3 multiple overloads (proposed version)
>
> I'm not too surprised. The lambda calls will look something like this:
>
> check(() -> String.format("map expected size m%d != k%d", map.size(),
> keys.length),
> map.size() == keys.length);
>
> Although the string formatting itself isn't performed unless the assertion
> fails, this is pretty much the worst case scenario for lambda. Every lambda
> is a capturing lambda, so the metafactory has to create a new lambda
> instance every time. However, the lambda itself is never actually called.
> That adds a lot of overhead.
>
> In addition, there are several cases where the captured variables aren't
> effectively final, so I had to copy them into local variables and capture
> those instead. This was merely annoying, but it's a inconvenient and it
> adds a bit of clutter.
>
> Anyway, good idea, but lambda didn't really work for this. I'm going to
> push my original patch.
>
> s'marks
>
More information about the core-libs-dev
mailing list