[JAVA] Ich habe mich gefragt, ob Stream / ParallelStream / For mehrere Kerne verwenden würde, also habe ich nachgeschlagen.

Wird For Loop mehrere Kerne verwenden? Was ist mit Stream / ParallelStream? Ich verglich es mit dem einfachen, auf das ich neugierig war.

Für das Verhalten von Stream und Parallel Stream ist die Folie von Java 8 Streams: Lambda in Top Gear von JavaOne 2013 zu sehen.

Derzeit wird jede Messung nach mehrmaliger Durchführung durchgeführt.

Für Schleife

public class StreamTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        for (int i = 1; i <= 200000; i++) {
            list.add(String.valueOf(i));
        }

        long start = System.currentTimeMillis();

        String str = "";
        for (String val : list) {
            str += val;
        }
        System.out.println(str);

        long end = System.currentTimeMillis();
        System.out.println((end - start)  + "ms");
    }
}

Die erforderliche Zeit beträgt 42801 ms

for.png

Es scheint, dass alle 4 Kerne verwendet werden. Die CPU-Auslastungsrate pro Kern erreicht jedoch nicht 100%.

Stream

public class StreamTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        for (int i = 1; i <= 200000; i++) {
            list.add(String.valueOf(i));
        }

        long start = System.currentTimeMillis();

        Optional<String> str = list.stream().reduce((val1, val2) -> val1 + val2);
        System.out.println(str);

        long end = System.currentTimeMillis();
        System.out.println((end - start)  + "ms");
    }
}

Die erforderliche Zeit beträgt 41039 ms

stream.png

Fast das gleiche wie bei For Loop. Ich habe das Gefühl, dass die Last im Großen und Ganzen leicht ist.

ParallelStream

public class StreamTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        for (int i = 1; i <= 200000; i++) {
            list.add(String.valueOf(i));
        }

        long start = System.currentTimeMillis();

        Optional<String> str = list.parallelStream().reduce((val1, val2) -> val1 + val2);
        System.out.println(str);

        long end = System.currentTimeMillis();
        System.out.println((end - start)  + "ms");
    }
}

Die benötigte Zeit beträgt 1937 ms

parallelStream.png

Es endet, sobald alle Kerne für einen Moment 100% erreichen. Etwa 20 mal schneller. Übrigens, wenn die Anzahl der Elemente verringert wird, wird der Unterschied kleiner. Je größer die Anzahl der Elemente ist, desto größer scheint der Unterschied zu sein.

Zusammenfassung

(An Stellen, an denen ~~ verwendet werden kann ~~ An Stellen, an denen die Anzahl der zu verarbeitenden Elemente zunimmt) ParallelStream sollte aktiv berücksichtigt werden.

In Bezug auf ~~ For / Stream scheint es, dass die Verarbeitung auf mehrere Kerne verteilt ist, dass bei der synchronen Verarbeitung eine CPU-Wartezeit auftritt, um die Reihenfolge zu gewährleisten. Daher erreicht die Nutzungsrate pro Kern nicht 100% und die Verarbeitungszeit ist lang. ~~

~~ Um diesen Betrag muss Parallel Stream nicht auf die Synchronisierung warten, sodass die CPU immer läuft und die Nutzungsrate auf 100% gestiegen zu sein scheint. ~~

Es war unerwartet, dass ~~ für mehrere Kerne verwendet wurde, aber ansonsten war das Verhalten wie erwartet, so dass ich auf verschiedene Weise überzeugt war. ~~

~~ Übrigens wurde in diesem Test die Verarbeitungsreihenfolge auch in ParallelStream nicht gestört, aber ich denke, dass die Reihenfolge zufällig beibehalten wurde, da die Verarbeitungszeit in der Schleife konstant war. Im Gegenteil, selbst mit For / Stream war es meiner Meinung nach fast immer möglich, zum Zeitpunkt der Synchronisationsprüfung mit dem nächsten Prozess fortzufahren (es gab kein Warteurteil), aber die Tatsache, dass es immer noch einen solchen Geschwindigkeitsunterschied gibt, bedeutet, dass der Aufwand für die Bestellgarantie beträchtlich ist. Ist es gross? ~~

Die Reihenfolge der Verarbeitung oder die Reihenfolge der Ausgabeergebnisse stand nicht in direktem Zusammenhang mit dem Unterschied zwischen Stream und ParallelStream. Der Geschwindigkeitsunterschied war also eine reine Berechnung. Ich wurde über Parallel Stream völlig missverstanden ... Siehe Java 8 Streams: Lambda in Top Gear um 45:15. Vielen Dank für den Hinweis auf die Kommentare.

Recommended Posts

Ich habe mich gefragt, ob Stream / ParallelStream / For mehrere Kerne verwenden würde, also habe ich nachgeschlagen.
Ich wusste nicht, was ich in Mavens Bereich schreiben sollte, also habe ich es nachgeschlagen.