2013-03-19 17 views
9

Jaki jest najlepszy sposób na optymalizację deserializacji?Optymalizowanie deserializacji Gson

Obecnie używam standardowych metod Gson.toJson i Gson.fromJson do serializacji i deserializacji niektórych złożonych obiektów i staram się zredukować czas deserializacji, jeśli jest to możliwe.

Najbardziej złożony z moich obiektów zawiera 43 zmienne, jeśli to ma znaczenie.

Odpowiedz

13

Jeśli chcesz używać Gsona, a nie przełączać się na inny interfejs Java-to-from-JSON API, a wydajność automatycznej biblioteki danych Gsona nie jest wystarczająco dobra, można pozostać przy API Gson, i wycisnąć nieco umiarkowanie lepszą wydajność.

W najnowszych testach wydajności opublikowanych pod numerem https://github.com/eishay/jvm-serializers/wiki, wyniki sugerują, że łączna wydajność serializacji i deserializacji Gson może zostać poprawiona o około 25%, dzięki zastosowaniu the streaming API of Gson zamiast wiązania danych.

Należy zauważyć, że ta z reguły znacznie komplikuje realizację kodu, w którym roztwory porównywalne z jednej wkładki wykorzystujących interfejs Databinding np new Gson().toJson(something) są zastąpione (łatwo) kilkudziesięciu linii, oraz pętle i warunkowe. Koszt poprawionej wydajności jest więc bardziej skomplikowanym kodem.

Przykłady korzystania z interfejsu API do przesyłania strumieniowego w funkcji interfejsu API funkcji databinding, zobacz implementacje JsonGsonManual i JsonGsonDatabind w wersji the jvm-serializers project.

(Uwaga: Można również użyć modelu drzewa w interfejsie API Gson, zamiast funkcji API strumieniowania lub wiązania danych, ale wydaje się, że nie zapewnia on żadnych ulepszeń wydajności w porównaniu z wiązaniem danych. Na przykład zobacz JsonGsonTree.)

3

Nie ma sposobu na poprawę czasu serializacji i deserializacji biblioteki Gson.

Jak powiedział programista Bruce, jeśli czas wykonania naprawdę ma dla ciebie znaczenie, spójrz na bibliotekę Jackson. Jest to moim zdaniem nieco bardziej "skomplikowane" w użyciu, ale zostało udowodnione znacznie szybciej niż jakiekolwiek inne biblioteki json w benchmarkach.

Here to niektóre ze sprawdzonych metod poprawy wydajności z Jacksonem.

+2

Uzgodniono (oczywiście). Dodałbym, że podczas gdy opcje konfiguracyjne z Jacksonem są ogromne i znacznie bardziej znaczące niż te dostępne w API Gsona, dla prostego użycia odwzorowania pomiędzy strukturami danych wymagającymi minimalnego przetwarzania niestandardowego, Jackson, podobnie jak Gson, zapewnia prosty rozwiązanie liniowe. –

3

Gson jest znany i używany ze względu na łatwość użytkowania. Jeśli chcesz prędkości, musisz popatrzeć na super popularnego Jacksona Jsona.

Testowałem i porównywałem zarówno Gsona, jak i Jacksona i mogę powiedzieć, że w niektórych przypadkach Jackson jest 15 razy szybszy zarówno w przypadku serializacji, jak i deserializacji, nawet w przypadku bardzo dużych obiektów.

Aby uzyskać podobne zachowanie jako JSON używam następujące ustawienia

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; 
    } 
} 

To okaże się dać te same ciągi json jak Gson dla tych samych obiektów. Możesz go ustawić tak, aby używał tylko pobierających i ustawiających, jeśli chcesz. Radziłbym przeczytać o wszystkich adnotacjach json json dotyczących obsługi podtypów (użyteczne dla systemów typu RPC).

Moje przypadki użycia: Używam jacksona jako serializacji, gdy chcę zapisać obiekty typu blob w systemach pamięci masowej (Redis, Cassandra, Mongo, ... czasami też mysql). Używam go także jako serializacji dla API w stylu RPC dla systemów o dość dużym natężeniu ruchu, chociaż wolę używać Protobuf do tych, gdy jest to możliwe. W tym ostatnim przypadku używam Jacksona do bezpośredniego serializowania do bajtu [] lub strumienia dla lepszej wydajności.

Ostatnia uwaga: Program do odwzorowania obiektów jest bezpieczny dla wątków i posiadanie jednej statycznej instancji takiej, jak w przykładzie, który właśnie przesłałem, uniemożliwi ci lekkie naświetlenie.

EDIT: Mam świadomość, że mój przykład nie wynika wiele najlepszych praktyk wskazał na stronie jackson ale pozwala mi mieć proste do zrozumienia kodu, który wygląda jakby Gson.toJson i Gson.fromJson (co zacząłem zbyt i włączone później do Jackson)

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

0

wielkie rzeczy, że materia w optymalizacji dla JSON jest, aby wszystkie dane w jednym poziomie.

Jeśli obiekt ma inny obiekt jako pole, a to pole inny obiekt i tak dalej, co new zużywa trochę więcej czasu na deserializację.Jeśli wszystkie pola obiektu mają typy pierwotne, deserializacja będzie nieco szybsza.

Jackson i Gson są najlepszymi bibliotekami, które mogą Ci pomóc.

Powiązane problemy