Frage

Diese beiden Bibliotheken teilen die ähnliche Philosophie und daraus resultierende ähnliche Designentscheidungen.Aber dieser beliebte WSGI-Benchmark sagt eventlet ist viel langsamer als gevent.Was macht ihre Leistung so anders?

Soweit ich weiß, sind die Hauptunterschiede zwischen ihnen:

  • gevent absichtlich abhängig und gekoppelt ist libev (libevent, zuvor) während eventlet Definiert eine unabhängige Reaktorschnittstelle und implementiert bestimmte Adapter mit select, epoll, und ein verdrehter Reaktor dahinter. Führt eine zusätzliche Reaktorschnittstelle zu kritischen Leistungseinbußen?

  • gevent ist größtenteils in Cython geschrieben eventlet ist in reinem Python geschrieben. Ist nativ kompiliertes Cython so schneller als reines Python, für nicht so sehr rechnerische, sondern IO-gebundene Programme?

  • Primitive von gevent emulieren dabei die Schnittstellen von Standardbibliotheken eventletDie Grundelemente von unterscheiden sich vom Standard und bieten eine zusätzliche Ebene zur Emulation. Macht eine zusätzliche Emulationsschicht eventlet Langsamer?

  • Ist die Umsetzung von eventlet.wsgi einfach schlimmer als gevent.pywsgi?

Das wundert mich wirklich, denn im Großen und Ganzen sehen sie für mich so ähnlich aus.

War es hilfreich?

Lösung

Nun, gevent ist nicht „größtenteils“ in Cython geschrieben, obwohl einige kritische Abschnitte dies tun.

Cython macht einen großen Unterschied.Prozessoroptimierungen funktionieren viel besser mit kompiliertem Code.Beispielsweise scheitert die Verzweigungsvorhersage in VM-basierten Systemen, da die Indirektion der Verzweigung auf einer VM-Ausführungsebene für sie undurchsichtig ist.Der Cache-Footprint ist kleiner.Kompilierter Code macht hier einen großen Unterschied und IO kann sehr empfindlich auf die Latenz reagieren.

In ähnlicher Weise ist Libev sehr schnell.Dieselben Gründe.

Es scheint nicht so, als ob Eventlet den Select Hub hätte verwenden sollen (Python 2.6 verwendet normalerweise standardmäßig Epoll).Wenn es jedoch bei „Auswählen“ hängen bliebe, wäre es geschafft Wirklich langsam (da Python das ausgewählte fd_set hin und her in eine Python-Liste konvertieren muss, sodass es hässlich wird, wenn es sich mitten in einer Schleife befindet).

Ich habe kein Profil erstellt, bin aber bereit zu wetten, dass libev/libevent plus Cython den großen Unterschied macht.Bemerkenswerterweise befinden sich einige der Threading-Grundelemente in Cython in gevent.Das ist eine große Sache, denn viel Code berührt sie indirekt über IO und an manchen Stellen sogar über die Standardbibliothek.

Was die zusätzliche Emulationsebene von Eventlet betrifft, scheint es viel mehr Sprungkraft zu geben.Tatsächlich scheint der Codepfad Rückrufe zu erstellen und sie vom Hub aufrufen zu lassen.Eventlet scheint mehr Buchhaltung zu übernehmen als der Hub in Gevent.Allerdings habe ich es auch hier nicht profiliert.Was das Affenpflaster selbst betrifft, sehen sie ziemlich ähnlich aus.

Der WSGI-Server ist ein weiterer schwieriger Punkt.Bemerkenswert ist, dass das Header-Parsing in Gevent der Standardbibliothek übertragen wird, während sie es selbst in Eventlet implementieren.Ich bin mir nicht sicher, ob das eine große Auswirkung hat oder nicht, aber es wäre keine Überraschung, wenn da etwas lauern würde.Am aussagekräftigsten ist, dass der Eventlet-Server auf einer Monkey-Patch-Version der Standardbibliothek BaseHTTPServer basiert.Ich kann mir nicht vorstellen, dass das ganz optimal ist.Gevent implementiert einen Server, der die Emulation kennt.

Andere Tipps

Entschuldige die späte Antwort.

Es gibt zwei Hauptgründe für große Leistungsunterschiede in diesem Benchmark:

  • Wie bereits erwähnt, sind die kritischen Pfade von Gevent stark optimiert
  • Dieser Benchmark führt Stresstests durch.Es ist nicht mehr an E/A gebunden, da versucht wird, dass der Computer so viele Anfragen wie möglich ausführt.Und hier glänzt Cythonized Code.

„In der realen Welt“ passiert das nur bei „Schrägstrich“-Verkehrsstößen.Das ist wichtig und man sollte bereit sein, aber wenn es passiert, reagiert man, indem man weitere Server hinzufügt oder ressourcenintensive Funktionen deaktiviert.Ich habe keinen Benchmark gesehen, der bei steigender Auslastung tatsächlich weitere Server hinzufügt.

Wenn andererseits der Benchmark eine „normale Tages“-Auslastung simulieren würde (die von Website zu Website variieren würde), könnte sie im Allgemeinen jedoch durch Anforderung, zufällige Pause und Wiederholung angenähert werden.Je weniger Pause, desto mehr Verkehr simulieren wir.Auch die Client-Seite des Benchmarks müsste die Latenz simulieren.Unter Linux könnte dies mit awesome netem[1] erfolgen, andernfalls durch kleine Verzögerungen vor Recv/Send-Aufrufen (was sehr schwierig wäre, da Benchmarks normalerweise Bibliotheken höherer Ebenen verwenden).

Wenn diese Bedingungen nun erfüllt sind, würden wir tatsächlich E/A-gebundene Probleme bewerten.Aber die Ergebnisse wären nicht allzu großartig:Alle Kandidaten bedienten erfolgreich Lasten mit 10, 50 und sogar 200 qps.Langweilig, oder?So konnten wir die Latenzverteilung, die Zeit zur Bearbeitung von 99 % der Anfragen usw. messen.Gevent würde immer noch bessere Ergebnisse zeigen.Aber der Unterschied wäre kaum beeindruckend.

[1] Simulieren Sie verzögerte und verworfene Pakete unter Linux

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top