Redis
 sql >> Datenbank >  >> NoSQL >> Redis

Go JSON-Decodierung ist sehr langsam. Was wäre ein besserer Weg, es zu tun?

Das Parsen großer JSON-Daten scheint langsamer zu sein, als es sein sollte. Es würde sich lohnen, der Ursache auf den Grund zu gehen und einen Patch bei den Go-Autoren einzureichen.

Wenn Sie in der Zwischenzeit JSON vermeiden und ein Binärformat verwenden können, vermeiden Sie nicht nur dieses Problem; Sie werden auch die Zeit gewinnen, die Ihr Code jetzt damit verbringt, ASCII-Dezimaldarstellungen von Zahlen in ihre binären IEEE 754-Äquivalente zu parsen (und dabei möglicherweise Rundungsfehler einzuführen).

Wenn sowohl Ihr Sender als auch Ihr Empfänger in Go geschrieben sind, schlage ich vor, das Binärformat von Go zu verwenden:gob .

Wenn ich einen Schnelltest durchführe und eine Karte mit 2000 Einträgen generiere, jeder ein Slice mit 1050 einfachen Gleitkommazahlen, erhalte ich 20 MB JSON, was 1,16 Sekunden dauert, um auf meinem Computer zu parsen.

Für diese schnellen Benchmarks nehme ich das Beste aus drei Läufen, aber ich stelle sicher, dass ich nur die tatsächliche Parsing-Zeit mit t0 := time.Now() messe vor dem Unmarshal-Aufruf und dem Drucken von time.Now().Sub(t0) danach.

Mit GOB führt dieselbe Karte zu 18 MB an Daten, was 115 ms zum Analysieren dauert:
ein Zehntel der Zeit .

Ihre Ergebnisse variieren je nachdem, wie viele tatsächliche Schwimmer Sie dort haben. Wenn Ihre Floats viele signifikante Ziffern haben, die ihre Float64-Darstellung verdienen, enthalten 20 MB JSON viel weniger als meine zwei Millionen Floats. In diesem Fall wird der Unterschied zwischen JSON und GOB immer deutlicher.

Übrigens beweist dies, dass das Problem tatsächlich im JSON-Parser liegt, nicht in der Menge der zu analysierenden Daten oder in den zu erstellenden Speicherstrukturen (weil beide Tests ~ 20 MB Daten analysieren und dieselben Float-Slices neu erstellen.) Das Ersetzen aller Floats durch Strings im JSON gibt mir eine Parsing-Zeit von 1,02 Sekunden, was bestätigt, dass die Konvertierung von der String-Darstellung in binäre Floats eine gewisse Zeit dauert (im Vergleich zum einfachen Verschieben von Bytes), aber nicht der Hauptschuldige ist. P>

Wenn der Absender und der Parser nicht beide Go sind oder wenn Sie die Leistung noch weiter als bei GOB komprimieren möchten, sollten Sie Ihr eigenes angepasstes Binärformat verwenden, entweder mit Protokollpuffern oder manuell mit "encoding/binary" und Co. P>