Serialisieren und Deserialisieren von .NET Core vs Go-Daten

Hallo% Benutzername%


Meine Aufgabe war es, die Serialisierungsleistung für .NET Core und Golang zu vergleichen. Nachdem ich im Internet gesucht hatte, stieß ich auf ein Repository . Ein einfaches Beispiel für einen REST-Mikroservice wird betrachtet. Genau das brauche ich, dachte ich. Nachdem ich die Testergebnisse gesehen hatte, war ich überrascht. Nachdem ich mir den Quellcode angesehen hatte, wurde mir klar, was los war. Folgendes hat mir nicht gefallen:


  • Für die Serialisierung und Deserialisierung wird ein Array von 3 Elementen ausgewählt. Das reicht eindeutig nicht aus.
  • Für Golang werden nicht alle Funktionen der Sprache verwendet, aber wie Sie wissen, ist die in encoding / json integrierte Bibliothek langsam.
  • Infolgedessen vergleicht der Autor die Leistung der Turmfalken- und Net / http-Webserver.

Es waren diese Mängel, die zu einer detaillierteren Betrachtung der Leistung im Rahmen des oben beschriebenen Beispiels führten. Ich hoffe, Sie finden es interessant, die Ergebnisse zu kennen.


Zusammensetzung und Beschreibung der Software


Der Quellcode aus dem obigen Repository wurde ebenfalls als Grundlage genommen. Was wurde abgeschlossen:


  • Für die Server-API wird fasthttp verwendet.
  • Der API-Server antwortet mit Datensatz-Arrays.
  • Jeder Client verfügt über mehrere Methoden zur Überprüfung.

Geänderter Code ist im Repository verfügbar.


Zur Verdeutlichung eine beispielhafte JSON-Antwort von der Server-API:


[ { "Id":"id_8299119732867115081", "Name":"name_5541535679032008745", "Time":1566731141 }, ... { "Id":"id_2804604318195309547", "Name":"name_5914011395631118540", "Time":1566731142 } ] 

Kunden


Um die Leistung in jedem Dienst zu bewerten, werden drei Methoden implementiert:


  • Empfangen von Daten von der Server-API und Senden ohne Verarbeitung von [/ testNoProcess].
  • Empfangen von Daten von der Server-API - Deserialisierung, Serialisierung mithilfe von Reflection und Senden von [/ testReflection]. Für .NETCore wurde das Newtonsoft.Json-Paket verwendet, für Golang wurde encoding / json verwendet.
  • Empfangen von Daten von der Server-API - Deserialisierung, Serialisierung ohne Reflektion und Senden von [/ testNoReflection]. Für .NETCore wurde eine Span-basierte Lösung implementiert, um die Anzahl der Speicherzuweisungen zu minimieren. Golang hat eine fertige Lösung - die easyjson- Bibliothek, die sich ausschließlich auf der positiven Seite bewährt hat.

Basierend auf diesen Tests können Sie die relative Leistung von Webservern (Turmfalke und net / http) bewerten, den Leistungsabfall bei der Verarbeitung von Daten mithilfe von Reflection und ohne diese für Implementierungen in beiden Sprachen.


Beschreibung der Testmethode


Die Tests wurden in mehreren Schritten durchgeführt, um die Leistung jeder Sprache und jeder Implementierung zu bewerten.
Um eine Last zu erstellen, wurde das Bombardier- Dienstprogramm ausgewählt. Das Dienstprogramm wurde mit den folgenden Parametern gestartet: -c 125 –d 120s, was wie folgt interpretiert werden kann: Verwendung von 125 Threads mit einer Testzeit von 120 Sekunden.


Die Leistungsmessung wurde in 3 Stufen durchgeführt:


  1. RPS-API-Serverdimension. Die Messungen wurden durchgeführt, um den Einfluss von Verarbeitungsmethoden auf die Leistung jeder Methode beurteilen zu können.
  2. RPS-Messung der Antwortverarbeitung mittels Reflexion.
  3. Messen Sie die RPS-Antwortverarbeitung ohne Reflexion.

Basierend auf diesen Messungen wurden Daten zur Leistung der Antwortverarbeitung erhalten. Die Auslastung aller Prozessorkerne betrug 99,8-100%. Für die Bewertung wurden die Anfangsdaten von 10, 30, 100 und 500 Datensätzen ausgewählt. Arrays mit 500 Datensätzen in der Produktion sind nicht üblich, aber ich war interessiert zu sehen, wie sich jede der Sprachen verhält.


Prüfstand


Alle Tests wurden auf einer virtuellen Maschine mit Ubuntu Server 18.04 mit allen Updates für August 2019 ausgeführt. Es hat die folgenden Eigenschaften:


  • Prozessorkern I7-3770K - 4 Kerne.
  • RAM - 4 GB.

Zum Leistungsvergleich wurden .NET Core 2.2 und Golang 1.12 installiert.


Nun ist es an der Zeit, zu den interessantesten Ergebnissen überzugehen.


Ergebnisse


Unten finden Sie eine Tabelle mit den Testergebnissen.


alt text


Sie können sofort feststellen, dass Golang einen produktiveren Webserver hat. Der Unterschied beträgt ungefähr 12% im Vergleich zu Kestrel in .NET Core.
Basierend auf den obigen Daten wurden 2 Diagramme erstellt. Als nächstes können Sie den Vergleich von RPS deutlich sehen.


alt text


Aufgrund der schnelleren Net / http-Bibliothek zeigt Golang gute Ergebnisse für kleine Datenmengen. Mit zunehmendem Datenvolumen wird die Leistung mit Turmfalke verglichen.


Bei Verwendung der Reflexion für eine kleine Datengröße ist der RPS unter Berücksichtigung des Messfehlers ungefähr gleich. Mit zunehmender Datengröße zeigt .NET Core mehr RPS.


Beim Testen ohne Verwendung von Reflexion zeigten beide Sprachen einen Leistungsgewinn. Golang zeigt eine bessere Leistung, da es bei Tests ohne Verarbeitung anfänglich höhere RPS (Anforderungen pro Sekunde) aufweist. Bei kleinen Daten ist der Vorteil erheblich. Mit der Zunahme der Datengröße wird RPS fast verglichen. Beim größten Test von 500 Rekorden liegt Golang erneut vorn.


alt text


Bei Reflexionstests verlor Golang an allen Fronten. Der Leistungsabfall in den Worst-Case-Szenarien betrug über 60%. Die sofortige Implementierung der Serialisierung für die Leistung ist im Allgemeinen wertlos.
Ohne Reflexion war Golang in allen Tests schneller. Und mit dem Datenwachstum wächst der Vorteil von Golang nur noch. In jedem Fall führt die Weigerung, Reflektion zu verwenden, zu einer signifikanten Leistungssteigerung sowohl für Golang als auch für .NETCore, was im Allgemeinen zu erwarten ist.


Schlussfolgerungen


Welche Schlussfolgerungen können aus diesem kleinen Leistungsvergleich gezogen werden? Ich möchte dies in Form von Vor- und Nachteilen für jede der Lösungen formulieren. Beginnen wir mit Golang:


  • Es hat eine bessere Leistung und kann beispielsweise durch die Verwendung von fasthttp als Webserver weiter verbessert werden.
  • Dank Codegenerierung - bequemer Einsatz von Verarbeitungsmethoden ohne Reflexion.
  • Weniger Speicherverbrauch.

.NET Core bietet außerdem mehrere Vorteile:


  • Leistung ist für die meisten Fälle geeignet.
  • Meiner Meinung nach ist dies eine der besten und bequemsten Entwicklungsumgebungen für Visual Studio.

Das Ergebnis kann wie folgt zusammengefasst werden: Wenn Sie über eine REST-API verfügen und eine große, nicht zu komplizierte Geschäftslogik planen, ist es besser, Golang zu verwenden. In anderen Fällen können Sie .NET Core verwenden. Sollte ich vorgefertigte Lösungen von .NET Core nach Golang umschreiben? Jeder wird für sich selbst entscheiden.


Ich hoffe, Sie finden dieses Material nützlich. Alles gut

Source: https://habr.com/ru/post/de469271/


All Articles