Lambda filter performance

eldrior

Aktives Mitglied
Hallo,

Wenn ich mit einem Lambdaasudruck eine Liste filtern möchte, welche Variante ist dann schneller?

Java:
        List<Integer> l = new ArrayList();

        //Variante 1:
        l = l.stream().filter(x -> x > 20).filter(x -> x < 100).collect(Collectors.toList());
        //Variante 2:
        l = l.stream().filter(x -> x > 20 && x < 100).collect(Collectors.toList());

Nur nach meinem persönlichen Gefühl würde ich zu Variante 1 tendieren. Ich hätte da gedacht, dass es sich ein bisschen wie beim StringBuilder verhält, bei dem Variante A auch schneller, als Variante B ist:

Java:
        StringBuilder sb = new StringBuilder();

        //Variante A:
        sb.append("Hallo ").append("Welt!");
        //Variante B:
        sb.append("Hallo " + "Welt!");

Ich habe jetzt ein stark vereinfachtes Beispiel gewählt, natürlich könnte ich auch bspw. Personen nach Vor- und Nachname sowie Kleidergröße und IQ gleichzeitig filtern wollen...

Weiß da jemand etwas genaueres?
 
Ich würde mir einfach entsprechend große Listen generieren lassen und es einfach testen.

Ich würde auf Variante 2 tippen.
Grund: Methodenaufrufe sind teuer (man spart sich hier schon mal einen), außerdem wird die Liste nur 1x durchlaufen und gleich beide Sachen geprüft (bzw. die eine auch nur dann wenn die andere wahr ist)
 
Du hast natürlich recht, das hätte ich zuerst ausprobieren sollen, aber für alle, die das interessiert mein Ergebnis mit folgendem Code:

Java:
        List<Integer> l = new ArrayList();
        List<Integer> m = new ArrayList();
        Random rand = new Random();

        for (int i = 0; i < 5000000; i++)
        {
            l.add(rand.nextInt(500));
            m.add(rand.nextInt(500));
        }
        System.out.println("Start");

        long s1 = System.currentTimeMillis();
        l = l.stream().filter(x -> x > 20).filter(x -> x < 100).collect(Collectors.toList());
        long s2 = System.currentTimeMillis();

        System.out.println(s2 - s1);

        s1 = System.currentTimeMillis();
        m = m.stream().filter(x -> x > 20 && x < 100).collect(Collectors.toList());
        s2 = System.currentTimeMillis();

        System.out.println(s2 - s1);

So wie er da steht ist Variante 1 immer schneller.
Ändert man den Code bei beiden Versionen so ab:
Java:
X.stream().parallel()...
dann ist Versioin 2 durchgehend deutlich schneller. Ich werde wenn ich zu Hause bin mal eine größere Testreihe starten 🙂
 

Zurück
Oben