When to use functional interface? (Java 8)

3k Views Asked by At

I recently switched over to developing my software for Java 8, and I've been slowly improving my use of Java 8 and becoming comfortable with Java 8, and in doing so I've started implementing more and more functional interfaces, and recently NetBeans has started to suggest that I swap some of my for loops over to functional interfaces, but from the way the program is running it seems much slower than simply using a for loop (1.9 sec runtime vs. .9 sec respectively). So my question is-- is it worth using functional interfaces in the place of for loops? When in general should one use functional interfaces? Are functional interfaces more efficient in some other ways? Thanks in advance.

1

There are 1 best solutions below

2
On BEST ANSWER

if your lambdas do not use many capturing variables, then i believe that the performance will be more comparable to a standard for loop. the the advantages of using lambdas are easier parallelization (although for ordered streams this could potentially result in slower performance), and an easier to read syntax. also be aware that the hotspot compiler will change the results over time (your first loop execution will most likely be slower than your last).

i do not know the specifics, but in the worst case situation, you lambda may be implemented as an anonymous class. in the best case, it will just be a MethodHandle.

a quick test:

public class Test {

    public static void main(String... args) {
        Random r = new Random(42);
        for(int i = 0; i < 10; i++) {
            testFor();
            testLambda();
        }
    }

    protected static final int TestLength = 1024 * 1024 * 16;

    protected static int result;

    protected static void testFor() {
        Random r = new Random(42);
        long start = System.currentTimeMillis();
        for(int i = 0; i < TestLength; i++) {
            result = r.nextInt(TestLength);
        }
        long end = System.currentTimeMillis();
        System.out.printf("testFor = %dms%n", end - start);
    }

    protected static void testLambda() {
        Random r = new Random(42);
        IntStream stream = IntStream.iterate(0, i -> r.nextInt(1024 * 1024));
        long start = System.currentTimeMillis();
        stream.limit(TestLength).forEach(i -> {result = i;});
        long end = System.currentTimeMillis();
        System.out.printf("testLambda = %dms%n", end - start);
    }

}

the results:

testFor = 209ms
testLambda = 207ms
testFor = 210ms
testLambda = 206ms

for a parallel stream the results where actually slower (around 2x on my machine) because the stream was ordered and each thread has a lot of synchronization overhead, compared to the work being done (just result = i)