你好,歡迎來到IOS教程網

 Ios教程網 >> IOS訊息 >> 關於IOS >> iOS JSON 模型轉換庫評測

iOS JSON 模型轉換庫評測

編輯:關於IOS

iOS JSON 模型轉換庫評測

iOS 開發中總會用到各種 JSON 模型轉換庫,這篇文章將會對常見的幾個開源庫進行一下評測。評測的內容主要集中在性能、功能、容錯性這幾個方面。

評測的對象:

Manually
手動進行 JSON/Model 轉換,不用任何開源庫,可以進行高效、自由的轉換,但手寫代碼非常繁瑣,而且容易出錯。

YYModel
我造的一個新輪子,比較輕量(算上 .h 只有 5 個文件),支持自動的 JSON/Model 轉換,支持定義映射過程。API 簡潔,功能也比較簡單。

FastEasyMapping
Yalantis 開發的一個 JSON 模型轉換庫,可以自定義詳細的 Model 映射過程,支持 CoreData。使用者較少。

JSONModel
一個 JSON 模型轉換庫,有著比較簡潔的接口。Model 需要繼承自 JSONModel。

Mantle
Github 官方團隊開發的 JSON 模型轉換庫,Model 需要繼承自 MTLModel。功能豐富,文檔完善,使用廣泛。

MJExtension
國內開發者"小碼哥"開發的 JSON 模型庫,號稱性能超過 JSONModel 和 Mantle,使用簡單無侵入。國內有大量使用者。

性能評測:

所有開源庫代碼更新至 2015-09-18,以 Release 方式編譯,運行在 iPhone 6 上,代碼見https://github.com/ibireme/YYModel/tree/master/Benchmark。

用例1:GithubUser
從 https://api.github.com/users/facebook 獲取的一條 User 數據,去除 NSDate 屬性。
該 JSON 有 30 行,大部分屬性是 string,少量是 number。這個用例主要是測試最基礎的 Model 相關操作。
每次測試執行 10000 次,統計耗時毫秒數。

iOS JSON 模型轉換庫評測

用例2: WeiboStatus

從官方微博 App 抓取一條內容完整的微博數據,JSON 總共有 580 行(是的,一條微博需要這麼大數據量),包含大量嵌套對象、容器對象、類型轉換、日期解析等。這個用例主要是測試在復雜的情況下不同庫的性能。
每次測試執行 1000 次,統計耗時毫秒數。

iOS JSON 模型轉換庫評測

測試結果如下:

Mantle 在各個測試中,性能都是最差的
JSONModel 和 MJExtension 性能相差不多,但都比 Mantle 性能高。
FastEasyMapping 相對來說性能確實比較快。
YYModel 性能高出其他幾個庫一個數量級,接近手寫代碼的效率。

FastEasyMapping 不支持 NSCoding 協議,所以不能進行 Archive 的性能測試。
MJExtension 在處理復雜對象轉為 JSON 時,存在錯誤。

(此處我也測試了一些 Swift 的項目,例如 ObjectMapper、JSONHelper、ModelRocket,性能比 Mantle 還差很多,這裡就不進行對比了。)

 

容錯性:

容錯性主要是測試在默認情況下,當 JSON 格式錯誤時,Model 框架是否會產生錯誤結果或造成 Crash。

用例 YYModel FastEasyMapping JSONModel Mantle MJExtension JSON 屬性是 number
Model 屬性是 NSString ✅ NSString 🚫 NSNumber ✅ NSString ⚠️ model nil ✅ NSString JSON 屬性是 string "100"
Model 屬性是 int ✅ 100 🚫 Crash 🚫 Crash ⚠️ model nil ✅ 100 JSON 屬性是 string "2009-04-02T03:35:22Z"
Model 屬性是 NSDate ✅ NSDate 🚫 NSString ✅ NSDate ⚠️ model nil 🚫 NSString JSON 屬性是 string
Model 屬性是 NSValue ✅ nil 🚫 NSString 🚫 crash ⚠️ model nil 🚫 NSString

YYModel 和 Mantle 都會進行對象類型檢查,避免將錯誤的對象類型賦值到屬性,以避免潛在的 Crash 問題。不同的是 YYModel 會嘗試自動轉換,轉換失敗時留空;而 Mantle 遇到類型不匹配時,直接把錯誤向上返回,從而終止了整個轉換過程,但這麼做更方便調試。

MJExtension 會對部分對象進行自動轉換(比如 NSString 和 NSNumber 之間的轉換),但當自動轉換不能完成時,它會直接把 JSON 對象賦值給類型不匹配的 Model 屬性。這樣的結果會導致稍後 Model 在使用時,造成潛在的 Crash 風險。

JSONModel 並沒有對錯誤類型的檢測,並且沒有對 App 的保護,當出現異常時,會導致整個 App Crash,非常危險。

FastEasyMapping 表現則是最差的,它沒有自動轉換的機制,當遇到類型不匹配時,會導致錯誤的類型賦值,甚至直接 Crash。

 

功能:

功能 YYModel FastEasyMapping JSONModel Mantle MJExtension 相同屬性名自動映射 ✅ 🚫 ✅ ✅ ✅ 自定義屬性轉換方式 🚫 ✅ 🚫 ✅ 🚫 NSCoding ✅ 🚫 ✅ ✅ ✅ hash/equal ✅ 🚫 ✅ ✅ 🚫 CoreData 🚫 ✅ 🚫 ✅ ✅

就功能來說,Mantle 的可定制性最高,功能相對比較豐富。
YYModel、JSONModel、MJExtension 使用比較簡單,但功能相對 Mantle 稍弱。
FastEasyMapping 功能最少,使用也不算方便。

侵入性:

Mantle 和 JSONModel 都需要 Model 繼承自某個基類,靈活性稍差,但功能豐富。

YYModel、MJExtension 都是采用 Category 方式來實現功能,比較靈活,無侵入。
但注意 MJExtension 為 NSObject/NSString 添加了大量沒有前綴的方法,且方法命名比較通用,極易和一個工程內的其他類造成沖突。

FastEasyMapping 采用工具類來實現 Model 轉換的功能,最為靈活,但使用很不方便。

結論:

如果需要一個穩定、功能強大的 Model 框架,Mantle 是最佳選擇,它唯一的缺點就是性能比較差。
如果對功能要求並不多,但對性能有更高要求時,可以試試我的 YYModel。

JSONModel 由於沒有類型檢測,可能會產生潛在的問題,這裡不推薦使用。
MJExtension 也缺乏某些必要的類型檢測,同時會帶來大量 Category 命名污染,這裡也不推薦使用。

Swift 相關的幾個庫性能都比較差,所以非 Swift 項目不推薦使用。

附: YYModel 性能優化的幾個 Tip:

1. 緩存
Model JSON 轉換過程中需要很多類的元數據,如果數據足夠小,則全部緩存到內存中。

2. 查表
當遇到多項選擇的條件時,要盡量使用查表法實現,比如 switch/case,C Array,如果查表條件是對象,則可以用 NSDictionary 來實現。

3. 避免 KVC
Key-Value Coding 使用起來非常方便,但性能上要差於直接調用 Getter/Setter,所以如果能避免 KVC 而用 Getter/Setter 代替,性能會有較大提升。

4. 避免 Getter/Setter 調用
如果能直接訪問 ivar,則盡量使用 ivar 而不要使用 Getter/Setter 這樣也能節省一部分開銷。

5. 避免多余的內存管理方法
在 ARC 條件下,默認聲明的對象是 __strong 類型的,賦值時有可能會產生 retain/release 調用,如果一個變量在其生命周期內不會被釋放,則使用 __unsafe_unretained 會節省很大的開銷。

訪問具有 __weak 屬性的變量時,實際上會調用 objc_loadWeak() 和 objc_storeWeak() 來完成,這也會帶來很大的開銷,所以要避免使用 __weak 屬性。

創建和使用對象時,要盡量避免對象進入 autoreleasepool,以避免額外的資源開銷。

6. 遍歷容器類時,選擇更高效的方法
相對於 Foundation 的方法來說,CoreFoundation 的方法有更高的性能,用 CFArrayApplyFunction() 和 CFDictionaryApplyFunction() 方法來遍歷容器類能帶來不少性能提升,但代碼寫起來會非常麻煩。

7. 盡量用純 C 函數、內聯函數
使用純 C 函數可以避免 ObjC 的消息發送帶來的開銷。如果 C 函數比較小,使用 inline 可以避免一部分壓棧彈棧等函數調用的開銷。

8. 減少遍歷的循環次數
在 JSON 和 Model 轉換前,Model 的屬性個數和 JSON 的屬性個數都是已知的,這時選擇數量較少的那一方進行遍歷,會節省很多時間。

原文地址http://blog.ibireme.com/2015/10/23/ios_model_framework_benchmark/

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved