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

Reply via email to