2017-02-23 24 views
1

找不到任何合適的回答,同時搜索互聯網...什麼是更好的解析時動態JSON數據使用方法:JToken或內置動態類型C#

我已經從服務器接收到的數據JSON。它的格式可能每次都有所不同,所以我必須使用動態對象。目前在我們的項目中,我們使用Newtonsoft.JSON類型的JToken類型,但是如果我們看看它的內部結構......恐怕有很多裝箱/拆箱的情況不好 - 我們應該使用盡可能少的內存因爲它是一個移動應用。

所以問題是:使用dynamic類型從c#本身(是的,儘管它的拳擊/拆箱太好)還是它們之間沒有區別?他們如何執行內存使用?有沒有人對他們做過一些基準測試?

也許對他們來說有一些很好的選擇?

在此先感謝

+0

與c#的動態庫相比,大多數在線響應更喜歡Newtonsoft.JSON。雖然,這隻能由設計師決定更好或更糟。您是否嘗試過運行任何測試來確定差異是否值得進行調查? – vipersassassin

+0

響應變量如何?大多數情況下可以修復一些附加屬性,還是完全可變? – dbc

+0

@vipersassassin不幸的是,我想我應該這樣做。我想也許社區的某個人已經完成了它或者類似 – Andrew

回答

3

如此看來,沒有人做過有關我的問題的東西,我做了我自己的測試,現在我婉牛逼分享我的成果。希望他們會很有幫助。

起初我想說,我對一些結果感到非常震驚和驚訝。

首先第一件事情和我的測試機配置:

  • 惠普Probook 450 G3筆記本採用英特爾酷睿CPU的2.40 GHz的i5-6200
  • 8 GB的RAM
  • 256MB SSD愛國者點燃M2的,高達560MB/s的讀取& 320MB/s寫入的IO
  • 希捷的1000 SATA硬盤GB
  • 的Windows 10專業版x64操作系統

測試很簡單:有一個json字符串,它的大小存儲在一個4.54 kB的文件中。我運行100個測試,每個測試創建1000個指定類型的對象(動態/ JToken/JContainer)。在每個測試期間我計數這些1000個對象被分配的存儲器實際量和解析JSON-字符串指定的對象類型所需要的時間。在所有測試完成後,我計算平均使用內存量和每個測試集的平均時間。基於式for 0 < i < n, S += SUM(i), a = S/n,通過簡單的算法計算平均計數器,其中S - 總和所有計數器,n - 量的測試(100),a - 平均計數器。內存使用由ProcessGC

數現在最有趣的部分(IMO) - 我的基準測試:)的結果

首先,我跑了使用Newtonsoft.JSON內置方法JToken.Parse()JContainer.Parse()測試。這兩組的產生如預期相同的結果(因爲JContainer是從JToken嵌套類型):

JToken/JContainer

魅力。內存使用情況:25。7 MB

平均價格:解析時間:223 ms

非常簡單。現在我跑testsusing JsonConver.Deserialize<T>(string json)方法反序列化的json數據在同一個JToken/JContainer型,我驚訝於一小

JsonConver.Deserialize(JSON字符串),以JToken/JContainer

平均內存使用: 22.0 MB

平均價格:解析時間:223毫秒

所以,對於我個人來說,這是一個小小的驚喜,對於JToken/JContainerParse()方法產生,其分配比你JsonConver.Deserialize<T>()方法去做更多的內存對象。真是出乎意料。

對於這一部分的最後一組測試的是與使用相同的方法JsonConver.Deserialize<T>(string json)類型dynamic

JsonConver.Deserialize(字符串JSON)到動態

魅力。內存使用:22.1 MB

平均解析時間:224毫秒

說實話,我期待一些不同的結果,但目前看來,JToken只是圍繞dynamic的包裝,這就是爲什麼他們使用相同的內存量並採用相同的解析時間。

所有的事情都可能是好的,但總是有一些「但」的條件。我用於測試的json數據體積小(當然,我們總是儘可能少地通過網絡發送數據)。我必須使用的真實對象實例具有更大的尺寸,並且對我運行另一個測試集的真實數據非常滿意。現在,尺寸爲270 kB的實際對象(與第一組中的4.54 kB相比)。結果讓我非常震驚。 JToken/JContainerParse()方法失敗!!!我的8 GB RAM機器出現內存異常!在我附近打開任務管理器後,我看到了我的測試程序的內存如何超過2 GB!我認爲這是我的測試結束,但我是雄心勃勃的人,所以我繼續。與JsonConver.Deserialize<T>()運行測試給我帶來的更多的成功:)

270kBs JsonConver.Deserialize(

魅力。內存使用:1.63 GB

平均解析時間:20秒

是的,它的真實:1.63 GB和20秒解析1000個對象爲JToken/JContainer類型。使用dynamic給了我相同的結果,所以我不會再複製它們

如果我沒有試圖用對象分析來測試我的json,這些測試將不會完整。所以,我創建了一個描述我的JSON結構和使用方法JsonConver.Deserialize<T>()類:

JsonConver.Deserialize()解析到POCO對象

魅力。內存使用:72 MB

平均解析時間:7.5。 s

1000個POCO對象的72 MB與1.63Gbs的動態數據相比較。

PS。而不是結論...當然,我們總是嘗試使用對象來處理我們的代碼中的數據,但有時我們必須處理動態。現在你可以看到C#中的對象有多高效了。此外,我建議你永遠不要使用JToken.Parse(),爲自己節省一點記憶。國際海事組織介紹,OOP真正幫助開發人員,讓我們的夜晚夢想成真。它的工作! :)

PPS。所有有興趣看到我的測試解決方案的人 - 歡迎使用github :)

相關問題