2013-03-19 11 views
9

Wie optimiert man die Deserialisierung am besten?Optimieren der Gson-Deserialisierung

Ich verwende derzeit die Standardverfahren Gson.toJson und Gson.fromJson zur Serialisierung und Deserialisierung einiger komplexer Objekte, und ich möchte die Deserialisierungszeit reduzieren, wenn es möglich ist.

Der komplexeste meines Objekts enthält 43 Variablen, wenn das wichtig ist.

Antwort

13

Wenn Sie Gson verwenden und nicht zu einer anderen Java-to-JSON-API wechseln möchten und die Leistung von Gson Automagic Databinding nicht gut genug ist, dann ist es möglich, mit der Gson-API zu bleiben, und drücken Sie etwas mäßig bessere Leistung aus.

In den letzten Runden von Leistungstests bei https://github.com/eishay/jvm-serializers/wiki geschrieben, legen die Ergebnisse nahe, dass die kombinierte Leistung von Gson Serialisierung und Deserialisierung möglicherweise um etwa 25% verbessert werden könnte, durch the streaming API of Gson statt Datenbindung verwenden. Man beachte, dass dies im Allgemeinen die Implementierung des Benutzercodes wesentlich erschwert, wobei Lösungen, die Einlinern vergleichbar sind, die die Datenbindungs-API verwenden, z. B. new Gson().toJson(something), durch (leicht) Dutzende von Zeilen einschließlich Schleifen und Bedingungen ersetzt werden. So sind die Kosten für die verbesserte Leistung komplizierter Code.

Beispiele für die Verwendung der Streaming-API im Vergleich zur Datenbindungs-API finden Sie in den Implementierungen JsonGsonManual und JsonGsonDatabind unter the jvm-serializers project.

(Hinweis: Anstelle der Streaming- oder Databinding-APIs könnte auch das Baummodell in der Gson-API verwendet werden. Es scheint jedoch keine Leistungsverbesserungen gegenüber der Datenbindung zu geben. Ein Beispiel finden Sie unter JsonGsonTree.)

3

Es gibt keine Möglichkeit, die Serialisierungs- und Deserialisierungszeit der Gson-Bibliothek zu verbessern.

Wie Programmierer Bruce sagte, wenn die Ausführungszeit wirklich wichtig für Sie ist, werfen Sie einen Blick auf die Jackson Bibliothek. Es ist meiner Meinung nach ein bisschen "komplizierter" zu verwenden, aber es hat sich viel schneller als alle anderen JSON-Bibliotheken in Benchmarks bewiesen.

Here sind einige Best Practices, um die Leistung mit Jackson zu verbessern.

+2

Einverstanden (offensichtlich). Ich würde hinzufügen, dass, während die Konfigurationsoptionen mit Jackson umfangreich und viel bedeutender sind als die, die mit der Gson-API verfügbar sind, Jackson für den einfachen Anwendungsfall des Mappings zwischen Datenstrukturen, die nur minimale benutzerdefinierte Verarbeitung erfordern, wie Gson einen einfachen bietet Linienlösung. –

3

Gson ist bekannt und verwendet für seine Benutzerfreundlichkeit. Wenn Sie Geschwindigkeit wollen, müssen Sie sich die super beliebte Jackson Json anschauen.

Ich habe sowohl Gson als auch Jackson getestet und getestet und ich kann Ihnen sagen, dass Jackson in einigen Anwendungsfällen sowohl bei der Serialisierung als auch bei der Deserialisierung 15mal schneller ist, selbst bei sehr großen Objekten.

Um ein ähnliches Verhalten wie Json erhalte ich die folgenden Einstellungen verwenden

public enum JsonMapper { 
    INSTANCE; 

    private final ObjectMapper mapper; 

    private JsonMapper() { 
     mapper = new ObjectMapper(); 
     VisibilityChecker<?> visibilityChecker = mapper.getSerializationConfig().getDefaultVisibilityChecker(); 
     mapper.setVisibilityChecker(visibilityChecker 
       .withFieldVisibility(Visibility.ANY) 
       .withCreatorVisibility(Visibility.NONE) 
       .withGetterVisibility(Visibility.NONE) 
       .withSetterVisibility(Visibility.NONE) 
       .withIsGetterVisibility(Visibility.NONE)); 
    } 

    public ObjectMapper mapper() { 
     return mapper; 
    } 
} 

Diese entpuppen wird exakt die gleichen json Strings als Gson für die gleichen Objekte zu geben. Sie können festlegen, dass nur Getter und Setter verwendet werden, wenn Sie möchten. Ich würde Ihnen raten, alle jackson json Annotationen für die Handhabung von Subtypen zu lesen (nützlich für RPC-ähnliche Systeme).

Meine Anwendungsfälle: Ich benutze Jackson als Serialisierung, wenn ich Blobs zu Speichersystemen speichern muss (Redis, Cassandra, Mongo, ... irgendwann auch mysql). Ich benutze es auch als Serialisierung für meine RPC-style APIs für ziemlich hohe Verkehrssysteme, obwohl ich Protobuf für diejenigen vorziehen, wenn möglich. In diesem letzten Fall benutze ich Jackson, um direkt in Byte [] oder Stream für eine bessere Leistung zu serialisieren.

Eine letzte Anmerkung: Der Objekt-Mapper ist Thread-sicher und mit einer statischen Instanz wie in dem Beispiel, das ich gerade eingereicht habe, wird verhindert, dass Sie den geringen Instanziierungsaufwand haben.

EDIT: Ich bin mir bewusst, dass mein Beispiel nicht viele der Best Practices auf der Jackson-Seite folgt, aber es ermöglicht mir, einfach Code zu verstehen, der wie die und Gson.fromJson aussieht (mit denen ich begann) zu und schaltete später Jackson)

Gson.toJson(object) =>JsonMapper.INSTANCE.mapper().writeValueAsString(object) Gson.fromJson(object, clazz) =>JsonMapper.INSTANCE.mapper().readValue(jsonString, clazz);

0

Die großen Sachen, die bei der Optimierung für json Rolle ist es, alle Daten zu halten, in nur eine Ebene.

Wenn ein Objekt ein anderes Objekt als sein Feld hat und dieses Feld ein anderes Objekt und so weiter, verbraucht jedes new ein wenig mehr Zeit für die Deserialisierung.Wenn alle Felder Ihres Objekts primitive Typen haben, wird die Deserialisierung etwas schneller.

Jackson und Gson bleiben die beste Bibliothek, um Ihnen zu helfen.