2013-03-19 213 views
9

優化反序列化的最佳方法是什麼?優化Gson反序列化

我目前使用標準的Gson.toJson和Gson.fromJson方法對一些複雜對象進行序列化和反序列化,如果可能的話我期望減少反序列化時間。

我的對象中最複雜的包含43個變量。

回答

13

如果你想使用Gson,而不是切換到另一個Java到/從JSON API,並且如果Gson的automagic數據綁定的性能不夠好,那麼可以使用Gson API,並擠出一些適度好的表現。

https://github.com/eishay/jvm-serializers/wiki上發佈的最新一輪性能測試中,結果表明Gson系列化和反序列化的組合性能可能會提高約25%,使用the streaming API of Gson代替數據綁定。請注意,這通常使用戶代碼的實現複雜化,其中與(例如)new Gson().toJson(something)的使用數據綁定API的單行程相比較的解決方案被替換爲(容易)幾十行,包括循環和條件。所以,改進性能的代價是更復雜的代碼。

對於使用流API與數據綁定API的實例,看看所述JsonGsonManualJsonGsonDatabind實施方式中,在the jvm-serializers project。 (注意:也可以在Gson API中使用樹型模型,而不是流式API或數據綁定API,但它似乎沒有提供任何比數據綁定更高的性能改進,例如,請參閱JsonGsonTree。)

3

沒有辦法改善Gson庫的序列化和反序列化時間。

由於程序員布魯斯說,如果執行時間真正的問題給你,看看在Jackson庫。在我看來,使用起來更「複雜」一些,但它已經被證明比基準測試中的其他json庫快得多。

Here是一些改善傑克遜表現的最佳實踐。

+2

同意(顯然)。我會補充一點,儘管Jackson的配置選項比Gson API的配置選項更廣泛和重要,但對於需要最小定製處理的數據結構之間映射的簡單用例,傑克遜像Gson一樣提供了一個簡單的線解決方案。 – 2013-03-22 19:35:26

3

Gson是衆所周知的,因爲它易於使用。如果你想要速度,你將不得不看看超人氣傑克遜傑森。

我已經測試和基準都GSON和傑克遜,我可以告訴你,在一些使用情況傑克遜是快15倍的序列化和反序列化,甚至在非常大的對象。

要獲得類似的行爲爲JSON我使用以下設置

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

這會變成給完全相同的JSON字符串作爲GSON爲同一對象。如果你願意,你可以將它設置爲只使用getter和setter。我建議你閱讀關於處理子類型的所有jackson json註釋(對RPC風格的系統有用)。

我用例:我用傑克遜系列化,當我需要保存斑點存儲系統(Redis的,卡桑德拉,蒙戈,...有時mysql的也行)。我還將它用作我的RPC風格API的序列化,用於相當高流量的系統,儘管我更喜歡在可能的情況下使用Protobuf。在這最後一種情況下,我使用Jackson直接序列化爲byte []或流以獲得更好的性能。最後

一個注意:對象映射器是線程安全的,有像我剛剛提交將阻止你有輕微的實例開銷例如一個靜態實例。

編輯:我知道我的例子並沒有遵循傑克遜頁面中指出的很多最佳實踐,但它允許我有簡單易懂的代碼,看起來像Gson.toJsonGson.fromJson(我開始也和接通以後傑克遜)

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

0

的偉大的東西,在優化重要的JSON是保持所有數據在短短的一個級別。

如果一個對象有另一個對象作爲它的領域,這一領域的另一個對象等等,每一個new消耗多一點的時間來反序列化。如果對象的所有字段都有原始類型,則反序列化會更快一些。

傑克遜和格森仍然是最好的圖書館來幫助你。