[Android] Đâu là best JSON Parser Library?

Tram Ho

[Android] Đâu là best JSON Parser library?

Lời mở đầu

Trong quá trình phát triển ứng dụng android, khi nhắc đến thư viện hiệu quả và dễ dùng để xử lý các công việc phức tạp với Network thì không thể không nhắc đến Retrofit.

Nhưng khi nói đến thư viện để tuần tự hóa các object thành các request hoặc phân tích các response JSON thành các object, chúng ta có một vài đối thủ. Hôm nay mình sẽ giới thiệu và phân tích cho các bạn thấy đâu là trình phân tích cú pháp JSON đỉnh nhất trong Android.

1. Tại sao các JSON Parser Library ra đời?

Đầu tiên trước khi biết đến các JSON Parser library chắc các bạn đã từng Parse Json trong android bằng cách tạo ra các đối tượng JSONObject hoặc JSONArray. Nếu như đối tượng json của chúng ta khá phức tạp thì công việc đó trở nên rất khó khăn, tốn thời gian và nhiều code hơn, khiến dự án ta phình lên một cách không cần thiết.

May mắn là hiện nay chúng ta có nhiều thư viện vô cùng mạnh mẽ trong việc chuyển đổi tự động từ ‘Object’ sang ‘json’ và ngược lại.

Gson – Thư viện phân tích cú pháp JSON của riêng Google dành cho Android và là thư viện phổ biến nhất (Có đến 18,6k star trên Github cao hơn so với Jackson – 6,0k và Moshi – 6,6k). Nó cũng là phiên bản ra đời sớm nhất, với phiên bản 1.0 được phát hành vào năm 2008
Jackson – Là đối thủ cạnh tranh rất lâu của Gson trong nỗ lực cung cấp trình phân tích cú pháp nhanh hơn và nhiều tính năng hơn. Phiên bản 1.0 của nó được phát hành vào năm 2009 có tên mã là “Hazelnut”.
Moshi – Là thư viện ra đợi sau và hiện đại nhất trong số 3 JSON Parser Library được phát hành đầu tiên là vào năm 2015. Nó đứa con được tạo ra bởi một số người đã làm việc trên Gson trong quá khứ và Square, cha đẻ của Retrofit

Và trong đầu tôi nảy lên một vài suy nghĩ.

  • ??? – Trong nhiều tình huống, trường hợp có thể cái này sẽ tốt hơn cái kia ?
  • Tôi – Oh! Maybe
  • ??? – Chúng ta làm một vài round để xem đâu là thằng best nhất?
  • Tôi – Đúng vậy! Chúng sẽ bắt đầu vào vấn đề để tìm ra

2. Cuộc chiến bắt đầu

Cuộc thi của chung ta sẽ có một số tiêu chí như sau để đánh giá,
Ban đầu mình nghĩ có đến 4 tiêu chí . Tuy nhiên, mình nghĩ rằng tiêu chí Dễ sử dụng là không cần thiết vì không có cái nào trong số 3 cái đặc biệt khó sử dụng, hầu hết đều được sử dụng phổ biến.

  1. Đặc trưng
  2. Độ tin cậy và xử lý lỗi
  3. Hiệu suất

2.1 Round-1 FEATURES (Đặt trưng)

Gson, JacksonMoshi đều hỗ trợ liên kết dữ liệu JSON hoàn chỉnh cho Java để tuần tự hóa các đối tượng Java thành ‘json’ và ngược lại. Tuy nhiên, trong số 3 điều này, chỉ có Jackson hỗ trợ phân tích cú pháp XML.

Cả 3 cũng hỗ trợ các bộ điều hợp kiểu tùy chỉnh, giúp ích rất nhiều khi phân tích các cấu trúc API phức tạp hơn mà không cần phải làm ngập dự án của bạn với các lớp dữ liệu không cần thiết chỉ vì mục đích phân tích phản hồi JSON của bạn. Cả 3 cũng hỗ trợ các loại chung và đủ khả năng cấu hình cho hầu hết các trường hợp sử dụng phổ biến.

Đối với sự khác biệt? Gson là đơn giản nhất trong số 3 nhưng điều đó có nghĩa là nó ít tính năng nhất. Jackson có hỗ trợ extensive annotation .
Một số annotations của Jackson:

Đây là những chú thích có thể được sử dụng trên cả hai lớp và thuộc tính để sửa đổi hành vi trong quá trình tuần tự hóa hoặc deserialisation. Lấy @JsonIgnoreProperties làm ví dụ. Theo tài liệu Java:

Annotation that can be used to either suppress serialization of properties (during serialization), or ignore processing of JSON properties read (during deserialization)”

Mình tạm dịch:

Annotation có thể được sử dụng để ngăn tuần tự hóa các thuộc tính (trong quá trình tuần tự hóa) hoặc bỏ qua việc xử lý các thuộc tính JSON đã đọc (trong quá trình giải mã hóa)”

Jackson có một số lượng lớn các annotations này cho phép rất nhiều sự linh hoạt khi nói đến tuần tự hóa và giải mã mà Gson không có hoặc sẽ cần nhiều nỗ lực hơn để làm như vậy.

Vậy còn Moshi thì sao? Moshi cũng không nằm trong danh sách tính năng. Bạn nhận được các bộ định lượng như @HexColor int cho phép nhiều biểu diễn JSON cho một loại Java duy nhất và một số phương pháp thuận tiện cho bộ điều hợp như JsonAdapter. failOnUnknown() cho phép bạn từ chối dữ liệu JSON không mong muốn.

Điều này được nêu một cách chi tiết ở comment của swankjesse’s trong một bài post trên Reddit

Tuy nhiên, hỗ trợ XML của Jackson cũng như số lượng Annotation tuyệt đối của nó (trên thực tế là chúng được tích hợp vào các Annotation dễ sử dụng) đưa nó lên đầu danh sách tính năng.

Do đó 1 điểm cho Jackon vòng này

2.2 Round-2 RELIABILITY & EROR HANDLING (Độ tin cậy và xử lý lỗi)

Đầu tiên hãy nói về Gson, bởi vì nó có một vài vấn đề trong lĩnh vực này. Trước hết, nó là một thư viện Java thuần túy. Bất kỳ người đam mê Kotlin nào cũng sẽ cho bạn biết lợi thế quan trọng nhất mà nó có so với Java là các kiểu nullable, và điều đó cho phép xử lý an toàn nói chung và tránh các ngoại lệ con trỏ null nói riêng.

Điều này có ý nghĩa gì đối với Gson? Vì đây là một thư viện Java, nó khởi tạo các class Kotlin của bạn mà không quan tâm đến khả năng vô hiệu của chúng và do đó các giá trị null có thể được deserialised thành các kiểu không null của Kotlin và gây ra lỗi runtime.

Không những vậy, , Gson còn gặp các vấn đề khác như rò rỉ chi tiết triển khai của các loại nền tảng vào JSON được mã hóa của bạn, Date được mã hóa không có múi giờ nên dữ liệu bị hỏng khi bộ mã hóa và bộ giải mã không chia sẻ múi giờ. Phần khó chịu của lỗi này là nó cũng rất nguy hiểm để sửa: chúng ta không biết ứng dụng nào đang mong đợi định dạng hiện tại và chúng ta không biết điều gì sẽ bị hỏng nếu chúng tôi thay đổi nó. (Gson sẽ đọc các ngày RFC 3339 giống như 1970–01–01T00:00:00Ztheo mặc định).

Những lý do này, trong số những lý do khác là nguồn cảm hứng đằng sau việc tạo ra Moshi, Nó được tạo ra để giải quyết những vấn đề mà Gson gặp phải. Moshi cũng có một số hỗ trợ Kotlin khá tốt và có thể còn nhiều hơn thế nữa.

Khi nói đến xử lý lỗi, Moshi cũng tự hào về các trường hợp ngoại lệ có thể dự đoán được. Nó sẽ tạo ra một IOException đối với các vấn đề IO và một JsonDataException về kiểu không khớp.

Đối với Jackson, mặc dù mô-đun cốt lõi của nó hoàn toàn là Java, nhưng nó có một mô-đun hỗ trợ Kotlin. Jackson cũng có nhiều lớp ngoại lệ duy nhất cho bạn biết chính xác lý do tuần tự hóa / deserialisation không hoạt động theo cách mà nó cần. Bài báo của Bealdung giải thích nó một cách hoàn hảo .

Nhưng nhìn sâu hơn, nhiều vấn đề trong số này là những vấn đề mà thư viện lẽ ra có thể xử lý tốt hơn để tránh hoàn toàn vấn đề.

Vì lý do này, Moshi giành chiến thắng khi nói đến độ tin cậy và xử lý lỗi.

2.3 Final Round PERFORMACE & SIZE (Hiệu suất và kích thướt)

Đã có rất nhiều bài kiểm tra điểm benchmaking đã được thực hiện cho 3 trình phân tích cú pháp JSON này, vì vậy chúng ta sẽ lấy từ các bài phân tích này:

Here’s why you probably shouldn’t be using the Gson library in 2018

Android JSON Parsers Comparison

Beyond Gson — Evaluating JSON Parsers for Android & Kotlin

Cái thứ ba trong danh sách này là cái gần đây nhất, với thử nghiệm được thực hiện vào tháng 10 năm 2019. Vì vậy, chúng ta sẽ xem xét điều đó trước.

Bài kiểm tra hiệu suất vào tháng 10 năm 2019 của Rob Pridham:

Trong các thử nghiệm được thực hiện bởi Rob Pridham vào tháng 10 năm 2019, cả trong thời gian thực hiện đầu tiên và trong các thử nghiệm tiếp theo sau đó, với Jackson là người chậm nhất và Gson cũng không quá xa. Anh ấy nói trong bài báo rằng không có gì ngạc nhiên khi Jackson là người chậm nhất khi xem xét Annotation sử dụng nhiều.

Tuy nhiên, điều đáng ngạc nhiên là Gson chậm hơn Moshi bao nhiêu, mặc dù thiếu cả tính năng và độ an toàn.

Hai bài kiểm tra khác từ năm 2018 và 2017 dường như cho kết quả khác nhau.

Bài kiểm tra hiệu suất vào tháng 8 năm 2018 của Danny Damsky:

Bài kiểm tra hiệu suất tháng 3 năm 2017 của Ilya Eremin:

Cả hai bài kiểm tra này đều cho thấy Jackson là người nhanh nhất và Moshi hoặc Gson là người chậm nhất.

Bây giờ chúng ta hãy tự tìm hiểu điều này. Tại sao Moshi lại chậm nhất trong 2 bài kiểm tra này, nhưng lại nhanh nhất bởi khá chênh lệch trong bài kiểm tra đầu tiên?

Tháng 5 năm 2018 là ngày phát hành 1.6.0 của Moshi, bổ sung thêm tính năng tạo mã kapt với xử lý Annotation. Điều này có nghĩa là bạn có thể Annotation các lớp dữ liệu Kotlin của mình để có các adapter nhỏ và nhanh được tạo cho chúng khi biên dịch chúng, do đó làm tăng đáng kể hiệu suất của Moshi.

Tất nhiên, thử nghiệm năm 2017 của Ilya Eremin không thể sử dụng điều này vì nó chưa được phát hành vào thời điểm đó và Danny Damsky, mặc dù sử dụng Moshi 1.6.0, đã không chọn chức năng kapt này trong khi thử nghiệm của Rob Pridham đã làm.

Điều đó giải thích tại sao kết quả bài kiểm tra của Moshi là nhanh nhất trong bài kiểm tra gần đây nhất, nhưng làm thế nào Jackson lại đột ngột nhảy xuống chậm nhất?

Đi tiếp một thử nghiệm nữa.

Save my ass: benchmark of json deserializers on Android

Bài kiểm tra hiệu suất tháng 12 năm 2018 của Milosz Moczkowski:

Tháng 12 năm 2018 và đột nhiên, Jackson một lần nữa chậm nhất và Moshi một lần nữa nhanh nhất. Được rồi, làm thế nào chúng ta có thể thử và giải thích tại sao Jackson lại chậm như vậy ở đây và trong bài kiểm tra năm 2019, nhưng lại nhanh nhất trong các bài kiểm tra cũ?

Tôi chỉ có thể đoán rằng đó là một trong hai điều:

  1. Gson đã có một sự thúc đẩy hiệu suất lớn vào cuối năm 2018, do đó vượt qua Jackson về hiệu suất (Moshi với kapt đã có)
  2. Tháng 8 năm 2018 và tháng 3 năm 2017 đã không sử dụng nhiều Annotation của Jackson

Chưa kể, số phương pháp của Jackson cao hơn nhiều so với của Gson hoặc Moshi. Danny Damsky đã đưa ra ý kiến này trong bài báo của mình, vì vậy chúng tôi sẽ sử dụng điều đó.

Moshi đi kèm với gói Okio nhiều gấp đôi số phương thức của nó, nhưng nếu bạn đang sử dụng các thư viện Square phổ biến khác như OkHttp (có thể là bạn), thì bạn đã có Okio

Trong cả hai trường hợp, Moshi với kapt giành chiến thắng cho cả hiệu suất và kích thước.

2.4 Result

Gson – 0

Jackson – 1

Moshi – 2

3 Kết luận

Moshi giành chiến thắng ở đây.

Gson khá được mong đợi vì nó đã ra đời sớm nhất nhưng nó lại không xuất sắc ở bất kỳ khía cạnh nào so với hai đối thủ còn lại

Jackson có nhiều tính năng nhưng có kích thướt lớn hơn và chậm hơn so với hai thủ còn lại. Độ tin cậy lại không bằng Moshi

Có tình huống nào mà GsonJackson sẽ là lựa chọn đáng mơ ước hơn Moshi không? Đối với Gson, nếu bạn hiện đang sử dụng nó trong một dự án mà không có vấn đề gì và không nhất thiết muốn dành thời gian để thực hiện di chuyển cho Moshi, thì hãy tiếp tục sử dụng Gson. Dẫu sao nó cũng là con của Google nên đội ngũ của họ vẫn đang làm việc để đảm bảo Gson là một thư viện vững chắc nhất có thể.

Bạn có thể chọn Jackson nếu bạn nghĩ rằng nhiều loại Annotationcủa nó sẽ hữu ích cho bạn, yêu cầu phân tích cú pháp dữ liệu bằng XML hoặc các định dạng khác. Nếu không, Moshi sẽ giúp bạn tốt nhất.

Bài chia sẻ này mình đã tham khảo các tài liệu trên mạng. Mong mọi nguời bỏ qua sai xót và góp ý cho mình cải thiện .  mình xin dừng bài viết ở đây! Cảm ơn mọi người đã theo dõi.

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo