Welche von Koroutinen (Goroutines und Kotlin Coroutinen) sind schneller? [geschlossen]

10

Kotlin corutines ist Zucker für endliche Zustandsmaschine und einige Aufgabenläufer (zum Beispiel Standard ForkJoinPool). Ссылка

Mit anderen Worten, es gibt noch keine Laufzeit-Korutinen in der Java / Kotlin-Laufzeitumgebung (dies kann sich jedoch mit Ссылка ). Die Kotlin-Coroutine ist nur sequentiell von Tasks, die nacheinander ausgeführt werden. Jede Aufgabe kann in einem beliebigen Thread aus dem Thread-Pool ausgeführt werden.

Go Runtime unterstützt "Coroutinen". Aber Göroutinen sind nicht die wirklichen Koroutinen. Goroutines erlaubt nicht das Setzen von Fließpunkten im Programm. Go lässt auch nicht zu, benutzerdefinierten Thread-Pool festzulegen. Sie können nur die Größe der Threads im Standardpool festlegen.

Erster Unterschied zwischen Kotlin-Koroutinen und Goroutinen ist, dass die Go-Laufzeit verwaltet, welche Coroutine in diesem Moment ausgeführt wird. Wenn Goroutine bei einigen IO-Operationen (oder Synchronisationsgrundelementen) blockiert ist, wählen Sie Optionen nächster Job, um sie auszuführen. In der JVM gibt es keinen intellektuellen Jobwechsel.

Aus diesem Grund kann Go den aktuell laufenden Job günstig ändern. Go muss nur wenige Registries ändern Ссылка . Aber einige Leute sagen, dass JVM Stapel von Threads verwenden kann, anstatt Register zu verwenden. Es gibt also kein Speichern und Laden von Registern.

Der zweite Unterschied zwischen Kotlin-Koroutinen und Goroutinen ist die Art der Koroutinen. Kotlin Coroutines ist stackless Koroutinen. Goroutines sind stapelbare Koroutinen. Alle Zustände von Kotlin-Koroutinen werden im Kotlin-Kontext gespeichert, der im Heap gespeichert wird. Goroutines-Status wird in Registern und Thread-Stack gespeichert.

Ich möchte wissen, welche Koroutinen (Goroutines und Kotlin-Coroutinen) bei E / A-gebundenen Aufgaben schneller sind? CPU-gebundene Aufgaben? Was ist mit Speicherverbrauch?

    
Max 21.10.2017, 15:01
quelle

1 Antwort

27

Koroutinen in Kotlin werden anders als in Go ausgeführt. Was also "schneller" ist, hängt von dem Problem ab, das Sie lösen, und von der Art des Codes, den Sie schreiben.

Im Allgemeinen ist es sehr schwierig, im Voraus zu sagen, welche für ein Problem, das Sie zur Hand haben, besser funktionieren wird. Sie müssen Benchmarks für Ihre speziellen Workloads ausführen, um es herauszufinden. Im Folgenden finden Sie jedoch eine allgemeine Zusammenfassung der wichtigsten Unterschiede, die Ihnen Hinweise geben sollten.

  • Kotlin-Routinen benötigen weniger Speicher pro einfacher Instanz als Go-Routinen. Eine einfache Coroutine in Kotlin belegt nur ein paar Dutzend Bytes Speicher, während eine Go-Routine mit 4KiB Stack-Speicher beginnt. Es bedeutet, dass, wenn Sie planen, buchstäblich Millionen von Koroutinen zu haben, dann Koroutinen in Kotlin Ihnen einen Vorteil gegenüber Go geben könnten. Es macht auch Kotlin Koroutinen besser geeignet für sehr kurzlebige und kleine Aufgaben wie Generatoren und faule Sequenzen.

  • Kotlin-Coroutinen können zu jeder Stapeltiefe gehen, jedoch weist jeder Aufruf der Suspending-Funktion ein Objekt im Heap für seinen Stapel zu. Ein Aufrufstapel in Kotlin-Koroutinen wird derzeit als eine verknüpfte Liste von Heap-Objekten implementiert. Im Gegensatz dazu verwenden Goroutinen in Go linearen Stapelspeicher. Dies macht das Suspendieren von tiefen Stapeln in Go effizienter. Also, wenn der Code, den du schreibst, sehr tief im Stapel hängt, wirst du vielleicht feststellen, dass Goroutines für dich effizienter sind.

  • Effizientes asynchrones IO ist ein sehr mehrdimensionales Designproblem. Ein Ansatz, der für eine Art von Anwendung effizient ist, kann einem anderen nicht die beste Leistung bringen. Alle IO-Operationen in Kotlin-Routinen werden von Bibliotheken implementiert, die in Kotlin oder Java geschrieben sind. Es gibt eine große Auswahl an IO-Bibliotheken, die für den Kotlin-Code verfügbar sind. In Go wird Asynchronous IO von Go Runtime unter Verwendung von Grundelementen implementiert, die für allgemeinen Go-Code nicht verfügbar sind. Wenn der Go-Ansatz zur Implementierung von IO-Operationen für Ihre Anwendung gut geeignet ist, können Sie feststellen, dass die enge Integration mit der Go-Laufzeit einen Vorteil bietet. Auf der anderen Seite können Sie in Kotlin eine Bibliothek finden oder selbst eine schreiben, die asynchrone IO auf eine Weise implementiert, die für Ihre Anwendung am besten geeignet ist.

  • Die Go-Laufzeit übernimmt die vollständige Kontrolle über die Ausführung der Ausführung von goroutines auf den physischen Betriebssystem-Threads. Der Vorteil dieses Ansatzes ist, dass Sie nicht über alles nachdenken müssen. Mit Kotlin-Routinen haben Sie eine fein abgestimmte Kontrolle über die Ausführungsumgebung Ihrer Coroutines. Dies ist fehleranfällig (z. B. können Sie einfach zu viele verschiedene Thread-Pools erstellen und Ihre CPU-Zeit beim Kontextwechsel zwischen ihnen verschwenden). Es bietet Ihnen jedoch die Möglichkeit, die Thread-Zuweisung und Kontextwechsel für Ihre Anwendung anzupassen. Zum Beispiel ist es in Kotlin einfach, Ihre gesamte Anwendung oder eine Teilmenge ihres Codes in einem einzigen Betriebssystem-Thread (oder Thread-Pool) auszuführen, um den Wechsel von Betriebssystem-Threads zu vermeiden, indem Sie einfach einen entsprechenden Code dafür schreiben.

Roman Elizarov 21.10.2017, 16:09
quelle