Frage

Für einige Caching für ein geplantes Projekt zu tun, ich denke, ich habe über Java Serialisierung nachgedacht. Das heißt, es sollte verwendet werden?

Jetzt habe ich zuvor geschrieben benutzerdefinierte Serialisierung und Deserialisierung (Externalizable) aus verschiedenen Gründen in den vergangenen Jahren. In diesen Tagen Interoperabilität hat sich noch mehr ein Problem und ich kann eine Notwendigkeit, mit .Net-Anwendungen zu interagieren, vorhersehen, damit ich der Verwendung einer plattformunabhängigen Lösung gedacht haben.

Hat jemand hatte keine Erfahrung mit High-Performance-Einsatz von GPB? Wie sieht es in Bezug auf Geschwindigkeit und Effizienz, mit Java native Serialisierung vergleichen? Alternativ gibt es andere Systeme eine Überlegung wert?

War es hilfreich?

Lösung

Ich habe mit Java native Serialisierung in Bezug auf die Geschwindigkeit nicht verglichen Protocol Buffers, sondern für die Interoperabilität Java native Serialisierung ist eine ernste No-No. Es ist auch nicht zu so effizient in Bezug auf Raum als Protocol Buffers seine in den meisten Fällen. Natürlich, es ist etwas flexibler in Bezug auf was sie speichern kann, und in Bezug auf Referenzen, usw. Protocol Buffers ist sehr gut, was für es bestimmt sind, und wenn sie Ihre Notwendigkeit passt es toll - aber es gibt offensichtliche Einschränkungen aufgrund der Interoperabilität (und andere Dinge).

Ich habe vor kurzem veröffentlicht einen Protocol Buffers Benchmarking-Rahmen in Java und .NET. Die Java-Version ist in der Haupt-Google-Projekt (in der Benchmarks Verzeichnis ), die .NET-Version ist in mein C # Hafenprojekt . Wenn Sie mit Java Serialisierung Geschwindigkeit PB Geschwindigkeit vergleichen wollen könnten Sie ähnliche Klassen und Benchmark sie schreiben. Wenn Sie allerdings in Interop interessiert sind, würde ich wirklich nicht geben native Java Serialisierung (oder .NET nativen binäre Serialisierung) einen zweiten Gedanken.

Es gibt andere Optionen für interoperable Serialisierung neben Protocol Buffers obwohl - Thrift , JSON und YAML in dem Sinn, und es gibt zweifellos andere.

EDIT: Okay, mit Interop nicht so wichtig zu sein, es ist einen Versuch wert, die verschiedenen Qualitäten aufzulisten, die Sie aus einem Serialisierung Rahmen wollen. Eine Sache, die Sie denken sollten, ist die Versionierung - das ist eine andere Sache, dass PB ist so konzipiert, gut zu handhaben, sowohl hin und her (so neue Software können alte Daten und umgekehrt lesen) - wenn Sie den vorgeschlagenen Regeln halten, natürlich :)

versucht zu haben, vorsichtig über die Java-Performance vs nativen Serialisierung zu sein, würde ich wirklich nicht überrascht sein, dass PB schneller sowieso war. Wenn Sie die Chance haben, verwenden Sie den Server vm - mein bisheriger Benchmarks den Server VM zeigte sein mehr als doppelt so schnell bei Serialisierung und Deserialisierung der Beispieldaten. Ich denke, der PB-Code des Servers VM JIT passt sehr gut:)

Wie Probe Leistungswerte, die Serialisierung und Deserialisierung zwei Nachrichten (ein 228 Bytes, ein 84750 bytes) Ich habe diese Ergebnisse auf meinem Laptop des Server VM mit:

Benchmarking benchmarks.GoogleSize$SizeMessage1 with file google_message1.dat 
Serialize to byte string: 2581851 iterations in 30.16s; 18.613789MB/s 
Serialize to byte array: 2583547 iterations in 29.842s; 18.824497MB/s 
Serialize to memory stream: 2210320 iterations in 30.125s; 15.953759MB/s 
Deserialize from byte string: 3356517 iterations in 30.088s; 24.256632MB/s 
Deserialize from byte array: 3356517 iterations in 29.958s; 24.361889MB/s 
Deserialize from memory stream: 2618821 iterations in 29.821s; 19.094952MB/s 

Benchmarking benchmarks.GoogleSpeed$SpeedMessage1 with file google_message1.dat 
Serialize to byte string: 17068518 iterations in 29.978s; 123.802124MB/s 
Serialize to byte array: 17520066 iterations in 30.043s; 126.802376MB/s 
Serialize to memory stream: 7736665 iterations in 30.076s; 55.93307MB/s 
Deserialize from byte string: 16123669 iterations in 30.073s; 116.57947MB/s 
Deserialize from byte array: 16082453 iterations in 30.109s; 116.14243MB/s
Deserialize from memory stream: 7496968 iterations in 30.03s; 54.283176MB/s 

Benchmarking benchmarks.GoogleSize$SizeMessage2 with file google_message2.dat 
Serialize to byte string: 6266 iterations in 30.034s; 16.826494MB/s 
Serialize to byte array: 6246 iterations in 30.027s; 16.776697MB/s 
Serialize to memory stream: 6042 iterations in 29.916s; 16.288969MB/s 
Deserialize from byte string: 4675 iterations in 29.819s; 12.644595MB/s 
Deserialize from byte array: 4694 iterations in 30.093s; 12.580387MB/s 
Deserialize from memory stream: 4544 iterations in 29.579s; 12.389998MB/s 

Benchmarking benchmarks.GoogleSpeed$SpeedMessage2 with file google_message2.dat 
Serialize to byte string: 39562 iterations in 30.055s; 106.16416MB/s 
Serialize to byte array: 39715 iterations in 30.178s; 106.14035MB/s 
Serialize to memory stream: 34161 iterations in 30.032s; 91.74085MB/s 
Deserialize from byte string: 36934 iterations in 29.794s; 99.98019MB/s 
Deserialize from byte array: 37191 iterations in 29.915s; 100.26867MB/s 
Deserialize from memory stream: 36237 iterations in 29.846s; 97.92251MB/s 

Die „Geschwindigkeit“ vs „Größe“ ist, ob der generierte Code für die Geschwindigkeit oder die Codegröße optimiert ist. (Die serialisierten Daten ist in beiden Fällen gleich. Die „Größe“ Version für den Fall vorgesehen ist, wo Sie eine Menge von Nachrichten haben definiert und wollen nicht viel Speicher für den Code zu übernehmen.)

Wie Sie sehen können, für die kleinere Nachricht kann es sein, sehr schnell - über 500 kleine Nachrichten serialisiert oder deserialisiert pro Millisekunde . Auch mit der 87K Nachricht Es dauert weniger als eine Millisekunde pro Nachricht.

Andere Tipps

Ein weiterer Datenpunkt: Dieses Projekt:

http://code.google.com/p/thrift-protobuf-compare /

gibt eine Vorstellung von der erwarteten Leistung für kleine Objekte, einschließlich Java Serialisierung auf PB.

Die Ergebnisse sind sehr unterschiedlich je nach Plattform, aber es gibt einige allgemeine Trends.

Sie können auch einen Blick auf FST , ein Drop-in-Ersatz für integrierte in JDK-Serialisierung, die schneller sein sollte und kleinere Ausgabe hat.

rohen Schätzungen auf den häufigen Benchmarking i in den letzten Jahren getan haben:

100% = binary / struct basierte Ansätze (z.B. SBE, FST-structs)

  • unbequem
  • Nachbearbeitung (build up "real" obejcts auf der Empfängerseite) Leistungsvorteile können auffressen und wird nie in Benchmarks
  • enthalten

~ 10% -35% protobuf & Derivate

~ 10% -30% schneller Serializer wie FST und KRYO

  • bequem, können deserialisiert Objekte meist direkt ohne zusätzliche manuelle Übersetzung Code verwendet werden.
  • kann für die Leistung (Anmerkungen, Klasse Registrierung)
  • gepimpt werden
  • bewahren Links in Objektgraph (kein Objekt serialisiert zweimal)
  • können zyklische Strukturen verarbeiten
  • generische Lösung, FST ist voll kompatibel zu JDK-Serialisierung

~ 2% -15% JDK-Serialisierung

~ 1% -15% schneller JSon (z Jackson)

  • kann keine Objektgraph handhaben, aber nur eine kleine Teilmenge von Java-Datenstrukturen
  • no ref Wiederherstellung

0,001 bis 1% Voll Graph JSon / XML (zum Beispiel JSON.io)

Diese Zahlen sollen einen sehr groben Reihenfolge-of-Größenordnung Eindruck geben. Beachten Sie, dass die Leistung eine Menge auf den Datenstrukturen abhängig serialisiert / gebenchmarkt. So einzelne einfache Klasse Benchmarks meist nutzlos (aber beliebt: zum Beispiel ignoriert Unicode, keine Sammlungen, ..)

.

siehe auch

http://java-is-the-new-c.blogspot.de/2014/12/a-persistent-keyvalue-server-in-40.html

http: //java-is-the-new-c.blogspot.de/2013/10/still-using-externalizable-to-get.html

Wenn Sie zwischen PB & nativen Java Serialisierung auf Geschwindigkeit und Effizienz sind verwirrend, gehen Sie einfach für PB.

  • wurde PB entworfen solche Faktoren zu erreichen. Siehe http://code.google.com/apis/protocolbuffers/docs/overview. html
  • PB Daten ist sehr klein, während Java Serialisierung ein ganzes Objekt zu replizieren neigt, einschließlich seiner Unterschrift. Warum ich immer meine Klassennamen erhalten, Feldnamen ... serialisiert, auch wenn ich es von innen nach außen an Empfänger wissen?
  • Denken Sie über die Sprachentwicklung. Es wird hart, wenn eine Seite verwendet Java, eine Seite verwendet C ++ ...

Einige Entwickler legen nahe, Thrift, aber ich würde Google PB verwenden, weil „ich in google glauben“ :-) .. Wie auch immer, es lohnt sich für einen Blick: http://stuartsierra.com/2008/07/10/thrift-vs -Protokoll-Puffer

Was tun Sie bedeutet, durch eine hohe Leistung? Wenn Sie Millisekunde Serialisierung wollen, empfehle ich Ihnen die Serialisierung Ansatz verwenden, die einfachste ist. Wenn Sie Untermillisekunde wollen, sind Sie wahrscheinlich ein binäres Format benötigen. Wenn Sie viel weniger als 10 Mikrosekunden wollen, sind Sie wahrscheinlich eine benutzerdefinierte Serialisierung benötigen.

Ich habe nicht viel Benchmarks für die Serialisierung / Deserialisierung aber nur wenige Unterstützung weniger als 200 Mikrosekunden für die Serialisierung / Deserialisierung.

gesehen

Plattformunabhängige Formate kommen zu einem Preis (in Ihr Zutun und Latenz) Sie sich entscheiden müssen, ob Sie können die Leistung oder die Plattformunabhängigkeit wollen. Allerdings gibt es keinen Grund, warum Sie nicht sowohl als Konfigurationsoption haben können, die Sie zwischen je nach Bedarf.

Hier ist das von der Wand Vorschlag des Tag :-) (Sie etwas in meinem Kopf nur gezwickt, dass ich jetzt versuchen will) ...

Wenn Sie über diese für die gesamte Caching-Lösung gehen kann es funktionieren könnte: Projekt Darkstar . Es wird als eine sehr hohe Leistung Game-Server konzipiert, die speziell so dass liest schnell (so gut für einen Cache). Es hat Java und C APIs so glaube ich (dachte, es ist eine lange Zeit her, dass ich es sah, und ich war nicht von diesem denke dann), die Sie Objekte mit Java retten konnten und sich zurück in C lesen und umgekehrt.

Wenn nichts anderes werde es dir etwas geben, auf heute zu lesen: -)

Für Draht freundliche Serialisierung, betrachten die Externalizable Schnittstelle. Verwendet geschickt, werden Sie intim know müssen, wie man optimal marshall und unmarshall bestimmte Bereiche zu entscheiden. Das heißt, Sie werden die Versionierung von jedem Objekt korrekt verwalten müssen - einfach zu un-marshall, aber wieder Rangier ein V2-Objekt, wenn Ihr Code unterstützt V1 entweder Pause, verlieren Informationen, oder noch schlimmer beschädigte Daten in einer Art und Weise Ihre Apps nicht in der Lage ist korrekt zu verarbeiten. Wenn Sie sich für einen optimalen Pfad suchen, passen sie keine Bibliothek Ihr Problem ohne einige Kompromisse lösen. Im Allgemeinen werden die Bibliotheken die meisten Anwendungsfälle passen und kommt mit dem zusätzlichen Vorteil, dass sie sich anpassen werden und verbessern im Laufe der Zeit ohne Ihre Eingabe, wenn Sie für eine aktive Open-Source-Projekt entschieden haben. Und sie könnten Performanceprobleme hinzufügen, führen Bugs und sogar Fehler beheben, die Sie noch nicht betroffen sind!

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