Deser: Góc nhìn mới về thư viện tuần tự hóa cho Rust
Deser là một thư viện tuần tự hóa (serialization) cho Rust được tác giả Armin Ronacher phát triển từ năm 2022, lấy cảm hứng từ Serde nhưng dùng kiến trúc hoàn toàn khác dựa trên sink và emitter lưu trên heap. Mục tiêu là giải quyết những hạn chế cố hữu của Serde như mô hình dữ liệu cố định, đệ quy trên call stack và việc dùng chung một bộ trait cho mọi định dạng.

Serde từ lâu đã là thư viện tuần tự hóa (serialization) trứ danh của Rust, góp phần không nhỏ vào trải nghiệm lập trình của cộng đồng. Tuy nhiên, sau nhiều năm sử dụng, tác giả Armin Ronacher nhận ra Serde vẫn tồn tại những hạn chế khó khắc phục vì chúng bắt nguồn từ chính thiết kế cốt lõi và bị ràng buộc bởi các cam kết ổn định (stability guarantees).
Những điểm yếu cố hữu của Serde
Serde được thiết kế nhằm phục vụ cả hai nhóm định dạng: tự mô tả (self-describing) như JSON, YAML, TOML và định dạng mà trình đọc phải biết trước kiểu dữ liệu như postcard, bincode hay protobuf. Điều này rất tiện lợi, nhưng dẫn đến ba quyết định thiết kế gây ra nhiều vấn đề:
- Một bộ trait dùng chung cho mọi định dạng: một số tính năng chỉ hoạt động với một số định dạng nhất định, và lập trình viên chỉ phát hiện khi chạy chương trình.
- Mô hình dữ liệu cố định làm mất thông tin khi đệm (buffer): các kiểu enum có tag nội bộ (internally tagged), enum không tag (untagged) và flatten đều phải đệm giá trị trước khi biết phải xử lý ra sao, khiến vị trí lỗi bị mất và các phần mở rộng phải dùng "tín hiệu in-band" để biểu diễn số có độ chính xác tùy ý.
- Đệ quy trên call stack: mỗi cấp lồng nhau tiêu tốn một lượng stack, và nếu đi qua nhánh không có giới hạn đệ quy, dữ liệu lồng sâu có thể làm sập tiến trình.
Một ví dụ điển hình: khi bật tính năng arbitrary_precision của serde_json, mô hình dữ liệu của Serde không có chỗ cho số chính xác tùy ý, nên thư viện phải dùng một map với khóa "ma thuật" để đánh dấu. Nhưng vì Cargo hợp nhất các feature, chỉ cần một crate bất kỳ trong cây phụ thuộc bật tính năng này là toàn bộ hệ thống bị ảnh hưởng.
Deser ra đời như thế nào?
Năm 2022, Ronacher bắt đầu thử nghiệm một thư viện có tên Deser — chính là chữ Serde đảo hai nửa. Ý tưởng cốt lõi là đảo ngược chiều tuần tự hóa: thay vì kiểu dữ liệu chủ động hỏi định dạng, Deser để định dạng thông báo kiểu của giá trị tiếp theo và đẩy các sự kiện (event) vào một sink.
Khi một sink gặp giá trị lồng nhau, nó không đệ quy mà trả về một sink mới cho một driver — thành phần giữ toàn bộ trạng thái trên heap (thực chất là một arena). Nhờ vậy, Deser không cần dùng call stack cho mỗi cấp lồng nhau.
Điều này cũng đồng nghĩa Deser không hỗ trợ các định dạng không tự mô tả như protobuf. Đó là một sự đánh đổi có chủ đích: muốn "sửa" Serde thì phải chấp nhận những thỏa hiệp khác.
Deser mang lại gì?
Deser hướng tới việc trở thành thư viện thay thế tương thích (drop-in replacement) cho Serde. Người dùng vẫn derive Serialize và Deserialize như thường lệ, chỉ khác là các thuộc tính (attribute) nhận biểu thức Rust thay vì chuỗi ký tự.
Điểm mạnh nổi bật của Deser nằm ở adapter là kiểu dữ liệu, nên có thể lồng ghép linh hoạt. Ví dụ, Hex có thể đặt bên trong Vec, và DisplayFromStr có thể nằm trong Vec rồi trong Option. Các validator cũng là adapter, cho phép kiểm tra dữ liệu ngay khi phân tích.
Deser cũng xử lý XML tốt hơn hẳn — điều mà Serde từ chối hỗ trợ. XML dùng namespace, nghĩa là tên phần tử phải được so khớp theo namespace chứ không theo tiền tố (prefix) mà tài liệu tình cờ sử dụng. Trong khi đó, quick-xml — crate XML phổ biến nhất cho Serde — bỏ qua tiền tố và namespace, khiến một phần tử cùng tên từ namespace khác bị chấp nhận nhầm.
Cái giá phải trả
Deser không hề miễn phí. Thiết kế dựa trên dynamic dispatch cùng sink và emitter trên heap gây ra chi phí hiệu năng đáng kể:
- Với JSON, Deser đọc nhanh hơn từ 33% đến chậm hơn 60% so với
serde_json, trung bình chậm hơn khoảng 10%. - Tốc độ ghi dao động từ nhanh gấp ba lần đến chậm hơn 70%, trung bình tương đương.
- Với YAML và TOML, Deser nhanh hơn rõ rệt, nhưng phần lớn nhờ chất lượng thư viện định dạng hơn là kiến trúc.
- Thời gian biên dịch tốt hơn chút ít, nhưng bản build release của mã derive nhanh hơn khoảng 2,3 lần so với Serde.
Ngoài ra, để thiết kế hoạt động được, Deser dùng unsafe bên trong — chủ yếu để giữ chuỗi sink mượn (borrowed sink) trên heap. Tác giả cho rằng điều này chấp nhận được trong thời đại của Miri và các công cụ kiểm tra hiện đại, nhưng thừa nhận nó khiến một số người e ngại.
Hệ sinh thái và kết luận
Deser hiện hỗ trợ gần như đầy đủ các định dạng quan trọng: JSON, JSONC, JSON5, HJSON, CBOR, MessagePack, YAML 1.1 và 1.2, TOML, XML, ba biến thể plist của Apple, CSV/TSV, dữ liệu urlencoded và biến môi trường. Ngoài ra còn có thể đính kèm path info, ghi lại vị trí dữ liệu, kiểm tra hợp lệ ngay khi phân tích, cầu nối sang Serde, chuyển đổi giữa các định dạng, hay tích hợp với Tokio.
Tuy nhiên, tác giả thẳng thắn thừa nhận gần như không thể thay thế hoàn toàn Serde, bởi quy tắc orphan (orphan rule) của Rust đã ăn sâu Serde vào hệ sinh thái. Deser nhiều khả năng sẽ đóng vai trò một lựa chọn thay thế hấp dẫn trong những tình huống cụ thể, đồng thời truyền cảm hứng để cộng đồng Rust khám phá thêm không gian thiết kế mới cho bài toán tuần tự hóa.
Với các lập trình viên Rust tại Việt Nam đang xử lý khối lượng lớn dữ liệu JSON không đáng tin cậy — chẳng hạn trong các hệ thống backend, log pipeline hay ứng dụng AI cần đọc dữ liệu huấn luyện — Deser là một cái tên đáng để theo dõi, dù chưa nên vội thay thế Serde trong các dự án đang vận hành ổn định.
Bài viết liên quan

Công nghệ
Nộp đơn xin việc lẽ ra nên khó hơn. Thật đấy
25 tháng 8, 2026

Công nghệ
Mô hình AI hàng đầu giỏi Vật lý đến đâu? Nghiên cứu mới chỉ ra các bài kiểm tra hiện hành đang đánh giá sai
16 tháng 9, 2026

Công nghệ
Báo cáo Drive Stats Q2/2026 của Backblaze: Tỷ lệ hỏng ổ cứng tăng vọt lên 1,73%
29 tháng 9, 2026