6

I have used this benchmark java8-lambda-performance-test and when running it I have done the followings:

1.Disabled Intrinsic usage

2.Disabled Inlining

3.Disabled Compiling mode

I have found out that disabling the two first optimizations has no effect on results.

Which is strange, and also when running the benchmark with and print intrinsic, I did not find any call to the intrinsic compiledLambdaForm

Since maths intrinsics are heavily used there _min,_pow... I was expecting that disabling intrinsics would have slown the performance

uraimo
  • 19,081
  • 8
  • 48
  • 55
Bionix1441
  • 2,135
  • 1
  • 30
  • 65
  • 1
    Nice statements of your results. If this is a problem then clearly outline why, and what you would have expected. Otherwise I seen no problem. – Brett Walker Jun 01 '15 at 12:19
  • I have edited my post – Bionix1441 Jun 01 '15 at 12:27
  • Having a look at the article all I can say is that it is quite old (Mar 17, 2014). There have been may Java 8 updates since this article. If you are using a different JVM version to that used by the author (which he doesn't state) then it is quite understandable that your testing shows different results. Try using an early Java 8 and see if that makes any difference. – Brett Walker Jun 01 '15 at 12:54
  • Jdk1.7 will not work since the implementation contains lambdas and streams – Bionix1441 Jun 01 '15 at 13:01
  • I said an early version of **Java 8** not Java 7. There have been 8 public releases of Java 8 starting at the initial release of Java 8 with the latest being Java 8u45. See here: http://www.oracle.com/technetwork/java/javase/8u-relnotes-2225394.html – Brett Walker Jun 01 '15 at 13:12
  • Ok thank you I will try – Bionix1441 Jun 01 '15 at 13:14

2 Answers2

4

The reason why you haven't noticed an expected performance effect is poorly written benchmark.
I rewrote the benchmark using JMH and the things finally got right.

package lambdademo;

import org.openjdk.jmh.annotations.*;

import java.util.List;

@State(Scope.Benchmark)
public class LambdaBenchmark {
    @Param("100")
    private static int loopCount;

    private static double identity(double val) {
        double result = 0;
        for (int i=0; i < loopCount; i++) {
            result += Math.sqrt(Math.abs(Math.pow(val, 2)));    
        }
        return result / loopCount;
    }

    private List<EmployeeRec> employeeList = new EmployeeFile().loadEmployeeList();

    @Benchmark
    public double streamAverage() {
        return streamAverageNoInline();
    }

    @Benchmark
    @Fork(jvmArgs = "-XX:-Inline")
    public double streamAverageNoInline() {
        return employeeList.stream()
                .filter(s -> s.getGender().equals("M"))
                .mapToDouble(s -> s.getAge())
                .average()
                .getAsDouble();
    }

    @Benchmark
    public double streamMath() {
        return streamMathNoIntrinsic();
    }

    @Benchmark
    @Fork(jvmArgs = {"-XX:+UnlockDiagnosticVMOptions", "-XX:DisableIntrinsic=_dpow,_dabs,_dsqrt"})
    public double streamMathNoIntrinsic() {
        return employeeList.stream()
                .filter(s -> s.getGender().equals("M"))
                .mapToDouble(s -> identity(s.getAge()))
                .average()
                .getAsDouble();
    }
}

Here are the results:

Benchmark                              Mode  Cnt     Score    Error  Units
LambdaBenchmark.streamAverage          avgt    5    71,490 ±  0,770  ms/op
LambdaBenchmark.streamAverageNoInline  avgt    5   122,740 ±  0,576  ms/op
LambdaBenchmark.streamMath             avgt    5    92,672 ±  1,538  ms/op
LambdaBenchmark.streamMathNoIntrinsic  avgt    5  5747,007 ± 20,387  ms/op

As expected, the benchmark with -XX:-Inline works 70% longer, and the version with Math intrinsics disabled appears to be 60 times slower!

Community
  • 1
  • 1
apangin
  • 92,924
  • 10
  • 193
  • 247
  • One question : Why did you code `private static int loopCount = Integer.getInteger("loopCount", 100);` instead of `int loopCount = 100;` – Bionix1441 Jun 10 '15 at 08:24
  • 2
    @Bionix1441 There's no particular reason for that. Either way will do. @AlekseyShipilev Right, `@Param` is better. I've updated the code. – apangin Jun 10 '15 at 11:27
1

I don't think that there is any effect of the intrinsics, because Lambda expressions uses mainly the class LambdaMetaFactory.So that is why both inlining and intrinsics has no effect on the lambda itself.

Now for the maths intrinsics my believe is that since they are only used in the identity method,which is only used in the case of LambdaExtraAverage and LambdaExtraSerial tests then they will not affect much the benchmark results.

Bionix1441
  • 2,135
  • 1
  • 30
  • 65