Kann die Verwendung von async-await geben Sie alle performance-Vorteile?
Wann immer ich lese über async
-await
, die use-case-Beispiel ist immer ein, wo es eine Benutzeroberfläche, die Sie nicht wollen, zu frieren. Entweder alle Programmier-Bücher/tutorials sind die gleichen-oder UI-blocking ist der einzige Fall, der async
-await
dass ich wissen sollte, wie ein Entwickler.
Gibt es Beispiele dafür, wie man nutzen könnte async
-await
zu Fristen performance-Vorteile in einem Algorithmus? Wie nehmen wir eine der klassischen Programmierung interview-Fragen:
- Finden die nächsten gemeinsamen Vorfahren, die in einem binären Baum
- Gegeben
a[0]
,a[1]
, ...,a[n-1]
Vertretung Ziffern der Basis 10 der Zahl, finden Sie die nächste höchste Zahl mit den gleichen Ziffern - Finden Sie den median von zwei sortierten arrays (d.h. die mittlere Anzahl, wenn du Sie Zusammenführen)
- Gegeben ein array von zahlen
1
,2
, ...,n
mit einer Zahl fehlen, finden Sie die fehlende Zahl - Finden die 2 größten zahlen in einem array
Gibt es eine Möglichkeit, das zu tun diese mit async
-await
mit performance-Vorteile? Und wenn ja, was, wenn Sie haben nur 1 Prozessor? Dann nicht Ihre Maschine, nur teilen seine Zeit zwischen Aufgaben eher als wirklich tun Sie in der gleichen Zeit?
Du musst angemeldet sein, um einen Kommentar abzugeben.
In dieses interview, Eric Lippert im Vergleich async-await mit Kochen, Frühstück machen. Es hat mir geholfen, eine Menge zu verstehen, die Vorteile von async-await. Suche irgendwo in der Mitte für 'async-await'
Angenommen, ein Koch, Frühstück zu machen. Er hat zu toast Brot und Kochen ein paar Eier, vielleicht machen Sie etwas Tee?
Methode 1: Synchron. Durchgeführt von einem thread. Sie beginnen, Toasten Sie das Brot. Warten Sie, bis das Brot getoastet wird. Entfernen Sie das Brot. Starten Sie mit kochendem Wasser, warten Sie, bis das Wasser kocht und legen Ihr ei. Warten Sie, bis das ei fertig ist, und entfernen Sie das ei. Starten Sie kochendes Wasser für den Tee. Warten Sie, bis das Wasser gekocht wird, und machen den Tee.
Youl finden Sie alle wartet. während der thread wartet, könnte es andere Dinge zu tun.
Methode 2: Async-await, noch ein thread Sie beginnen, Toasten Sie das Brot. Während das Brot wird getoastet starten Sie kochendes Wasser für die Eier und auch für den Tee. Dann starten Sie wartet. Wenn eine der drei Aufgaben fertig ist Sie der zweite Teil der Aufgabe, je nachdem, welche Aufgabe zuerst fertiggestellt. Also, wenn das Wasser für die Eier kocht zuerst Kochen Sie die Eier, und warten Sie wieder für jede der Aufgaben fertig zu stellen.
In dieser Beschreibung nur eine person (Sie) tut all das Zeug. Nur einem thread beteiligt ist. Das schöne daran ist, dass, weil es ist nur ein thread tut das, was der code sieht ziemlich synchron an den Leser und es ist nicht viel brauchen, um Ihren Variablen thread-sicher.
Es ist leicht zu sehen, daß auf diese Weise Ihr Frühstück wird bereit sein, in kürzerer Zeit (und Ihr Brot wird noch warm sein!). In der computer das Leben diese Dinge geschehen wird, wenn der thread muss warten, bis ein anderer Prozess beendet ist, wie das schreiben einer Datei auf einer Diskette, abrufen von Informationen aus einer Datenbank oder aus dem internet. Diese sind in der Regel die Art von Funktionen, wo sehen Sie eine asynchrone version der Funktion:
Write
undWriteAsync
,Read
undReadAsync
.Methode 3: stellen Sie den Köchen toast das Brot und die Eier Kochen, während Sie machen den Tee: Real asynchron. Mehrere threads Dies ist die teuerste option, denn es handelt sich um die Erstellung von separaten threads. In dem Beispiel von Frühstück machen, das wird wahrscheinlich nicht den Prozess zu beschleunigen sehr viel, weil relativ großen Zeiten des Prozesses, die Sie nicht tun eh nichts. Aber wenn zum Beispiel Sie müssen auch slice Tomaten, es könnte nützlich sein, zu lassen Sie einen Koch (separater thread) dies tun, während Sie tun, das andere Zeug mit async-await. Natürlich, von der Sie erwartet, zu tun ist erwarten für das Kochen, um seine aufschneiden.
Einem anderen Artikel, dass erklärt eine Menge, ist Async und Await geschrieben von die immer so hilfsbereit Stephen Cleary.
Das ist der häufigste Anwendungsfall für
async
. Der andere ist in Anwendungen der server-Seite, woasync
können Steigerung der Skalierbarkeit von web-Servern.Nicht.
Können Sie die Task Parallel Library, wenn Sie wollen-parallel-processing. Parallele Verarbeitung ist die Verwendung von mehreren threads, die Aufteilung der Teile eines Algorithmus auf mehrere cores in einem system. Parallelverarbeitung ist eine form von Parallelität (tun mehrere Dinge zur gleichen Zeit).
Asynchronen code ist völlig anders. Der Punkt der asynchronen code zu nicht Verwendung den aktuellen thread, während die operation im Gange ist. Async-code ist in der Regel-I/O-gebunden oder basiert off-Veranstaltungen (wie ein timer). Asynchroner code ist eine andere form der Parallelität.
Ich habe eine
async
intro auf meinem blog, sowie einen post auf wieasync
nicht verwenden-threads.Beachten Sie, dass die Aufgaben, die durch die Task Parallel Library, die geplant werden können, die auf threads und code ausführen. Die Aufgaben, die von der Task-Based Asynchronous Pattern nicht über code und auch nicht "ausführen". Obwohl beide Arten von Aufgaben werden vertreten durch den gleichen Typ (
Task
), Sie werden erstellt und verwendet werden, ganz anders; ich beschreibe diese Aufgaben delegieren und Aufgaben Versprechen im detail auf meinem blog.async
Steigerung der Skalierbarkeit von web-Servern?async
ermöglicht Ihnen, optimal zu nutzen deinen thread-pool.In kurzen und sehr Allgemeinen Fall - Nein, es wird in der Regel nicht. Aber es erfordert ein paar Worte mehr, weil "Leistung" verstanden werden kann, in vielerlei Hinsicht.
Async/await "spart Zeit' nur, wenn der 'job' wird I/O-bound ist. Jede Anwendung, um Arbeitsplätze, CPU-gebunden wird, stellen einige performance trifft. Das ist, weil, wenn Sie einige Berechnungen, die nehmen also 10 Sekunden auf Ihre CPU(s), dann das hinzufügen von async/await " - das heißt: Aufgabe der Erstellung, Terminierung und Synchronisation - einfach hinzufügen X extra-Zeit, die 10 Sekunden, die Sie noch brauchen, um zu brennen, auf die CPU(s) um den job zu erledigen. Etwas nah an der Idee von Amdahl-Gesetz. Nicht wirklich, aber ganz in der Nähe.
Jedoch gibt es einige 'aber..'s.
Zunächst, dass die Leistung trifft oft durch die Einführung von async/await sind nicht so groß. (vor allem, wenn Sie vorsichtig, nicht zu übertreiben).
Zweiten, da die async/await-erlaubt Ihnen das schreiben von I/O-interleaved code viel einfacher, bemerken Sie möglicherweise neue Möglichkeiten, um entfernen Wartezeiten auf I/O an Orten, wo Sie wären zu faul ( 🙂 ) zu tun, die es anders oder an Orten, wo es machen würde, den code zu schwer zu Folgen, ohne async/await syntax Güte. Zum Beispiel die Aufteilung der code um Anfragen im Netzwerk ist ziemlich offensichtlich, was zu tun, aber Sie können feststellen, dass D. H. Sie können auch aktualisieren, einige Datei-i/o an, dass nur wenige Orte, wo man schreiben CSVs Dateien oder Lesen von Dateien, Konfiguration, etc. Noch, beachten Sie, dass der Gewinn hier nicht durch async/await - es wird durch den code umschreiben, mit der Datei-i/o. Sie können das tun, ohne dass async/await auch.
Dritte, da einige i/o-ops sind einfacher, Sie können feststellen, dass da die CPU-intensive Arbeit zu einem anderen Dienst oder Gerät ist viel einfacher, die verbessern können Ihre wahrgenommene Leistung (ist kürzer " wall-clock time), aber der gesamte Ressourcenverbrauch steigen: eine weitere Maschine, die Zeit auf Netzwerk-ops, etc.
Vierten: UI. Sie wirklich nicht wollen, um Sie einzufrieren. Es ist so sehr leicht zu wickeln beide I/O-bound und CPU-bound jobs in Aufgaben und async/await auf Sie und halten Sie die Benutzeroberfläche reagiert. Deshalb sehen Sie es erwähnt überall. Jedoch, während die I/O-bound-ops idealerweise sollte der asynchrone bis in die Blätter zu entfernen, wie viel Leerlauf Wartezeit auf alle langen I/O -, CPU-bound jobs braucht nicht gespalten zu werden oder asyncized mehr als nur 1 level down. Mit riesigen monolithischen Berechnung job-verpackt in nur einer Aufgabe ist einfach genug, um die Benutzeroberfläche freigeschaltet. Natürlich, wenn Sie viele Prozessoren/Kerne, es immer noch lohnt, zu parallelisieren, was im inneren möglich ist, aber im Gegensatz zu I/O - split zu viel und Sie werden beschäftigt sein switching-Aufgaben statt kauen der Berechnungen.
Zusammenfassung: wenn Sie Zeit haben-unter I/O - async-ops kann viel Zeit sparen. Es ist schwer zu übertreiben asynchronizing I/O-Operationen. Wenn Sie die CPU-taking ops, fügt dann alles verbraucht mehr CPU-Zeit und mehr Speicher in der Summe, aber die wall-clock-Zeit kann besser durch die Aufteilung der Aufgabe in kleinere Teile, vielleicht können ausgeführt werden, auf mehrere Kerne gleichzeitig. Es ist nicht schwer, es zu übertreiben, so müssen Sie ein wenig aufpassen.
Meist du nicht gewinnen, im direkten Leistung (Aufgabe, die Sie durchführen, geschieht schneller und/oder weniger Speicher) als in der Skalierbarkeit; mit weniger threads, um die gleiche Anzahl der gleichzeitigen Aufgaben bedeutet, dass die Anzahl gleichzeitiger Aufgaben, die Sie tun können, ist höher.
Zum größten Teil daher, Sie nicht finden, eine gegebene operation eine Verbesserung in der Leistung, aber finden starke Nutzung hat eine verbesserte Leistung.
Wenn eine operation erfordert parallele Aufgaben, die wirklich etwas async (mehrere async-I/O), dann, dass die Skalierbarkeit kann jedoch von Vorteil, daß eine einzige operation. Da der Grad der Blockierung geschieht in threads reduziert wird, das passiert auch wenn Sie nur einen Kern, da die Maschine teilt seine Zeit zwischen nur jene Aufgaben, die derzeit nicht warten.
Diese unterscheidet sich von der parallelen CPU-gebundene Vorgänge, die (ob Sie nun mit Aufgaben oder anderweitig), wird in der Regel nur skalieren und die Anzahl der verfügbaren Kerne. (Hyper-Threading-Kerne Verhalten sich wie 2 oder mehr Kerne in einigen Punkten und in anderen nicht).
Wenn Sie eine CPU und mehrere threads in Ihre Anwendung, Ihre CPU schaltet zwischen den threads zu simulieren und parallele Verarbeitung. Mit async/await die asynchrone operation muss nicht thread mal, damit Ihnen mehr Zeit für andere threads Ihrer Anwendung zu tun job. Zum Beispiel Ihre Anwendung (non-UI) noch machen können HTTP-Aufrufe, und alles, was Sie brauchen, ist nur auf die Reaktion warten. Dies ist einer der Fälle, wenn der Vorteil der Verwendung von async/await ist groß.
Beim Aufruf
async DoJobAsync()
vergessen Sie nicht.ConfigureAwait(false)
um eine bessere Leistung für den nicht-UI-apps, die nicht brauchen, zu verschmelzen, zurück zum UI-thread-Kontext.Rede ich nicht schön-syntax, die hilft, eine Menge zu halten Sie Ihren code sauber.
MSDN
ConfigurAwait(false)
auf nicht-UI-thread (oder nicht-UI-app) - es wird keine Synchronisierung Kontext zu versuchen, wieder auf den ursprünglichen thread (und offensichtlichConfigurAwait(false)
ist flach aus schädlichen für ASP.Net - aber das ist common knowledge, so dass keine Notwendigkeit, explizit angeben).Den async-await-Funktionalität .NET ist nicht anders als andere frameworks. Es gibt keine performance-Vorteil, aber es ist nur erlaubt kontinuierliche Wechsel zwischen Aufgaben in einem einzigen thread statt eine Aufgabe blockieren den thread. Wenn Sie möchten, eine Leistung zu gewinnen, verwenden Sie den Task Parallel Library.
Besuchen https://msdn.microsoft.com/en-us/library/dd460717(v=vs. 110).aspx