Thực ra không cần giải pháp thay thế
ruby/json chậm hơn oj một chút, nhưng chênh lệch không lớn.
oj phổ biến vì hiệu năng, nhưng có thể gây ra nhiều vấn đề.
- Một trong những vấn đề của
oj là vấn đề bảo mật phát sinh do monkey patch thông qua Oj.mimic_JSON.
Trách nhiệm của monkey patch
Oj.mimic_JSON và Oj.optimize_rails thay thế các triển khai JSON kém hiệu quả hơn, nhưng có thể gây ra sự cố.
- Ví dụ, chúng có thể bỏ qua tùy chọn
script_safe, khiến ứng dụng dễ bị tấn công XSS.
- Monkey patch cần được thực hiện cẩn trọng và phải ứng phó an toàn theo sự tiến hóa của API.
Tính bất ổn định
oj từng là một trong những nguyên nhân chính gây crash Ruby trong vận hành quy mô lớn.
oj được phát triển rất tích cực nên các lỗi crash mới thường xuyên xuất hiện.
- Trong codebase của
oj từng tồn tại những hack lộn xộn khó có thể tin cậy.
Công việc nền tảng
- Mục tiêu là cải thiện
ruby/json để đạt hiệu năng gần với oj, qua đó giảm nhu cầu monkey patch.
- Đã thiết lập benchmark và dùng C profiler để phân tích hiệu năng.
Tránh kiểm tra trùng lặp
- Trong benchmark
JSON.dump, hiệu năng được cải thiện bằng cách tránh kiểm tra UTF-8 trùng lặp.
- Loại bỏ công việc trùng lặp giữa
rb_enc_str_asciionly_p và isLegalUTF8 giúp tăng hiệu năng 3%.
Kiểm tra điều kiện rẻ hơn và có khả năng đúng cao hơn trước
- Trong hàm
fbuffer_inc_capa, việc tối ưu điều kiện kiểm tra xem buffer đã được cấp phát hay chưa đã mang lại mức tăng hiệu năng 15%.
Giảm chi phí cấu hình
- Việc giảm chi phí cấu hình của
ruby/json đã cải thiện đáng kể hiệu năng trong microbenchmark.
Tránh dò theo con trỏ
- Loại bỏ lời gọi
rb_enc_get giúp cải thiện hiệu năng 8%.
Bảng tra cứu
- Sử dụng bảng tra cứu đã cải thiện hiệu năng dump chuỗi JSON lên 30%.
Còn tiếp
- Vẫn còn nhiều tối ưu hóa khác, sẽ được đề cập trong bài viết tiếp theo.
1 bình luận
Ý kiến trên Hacker News
Việc dùng jbuilder mặc định của Rails là một trong những nguyên nhân khiến việc render JSON chậm
Tò mò không biết có thông tin nào về thời gian mà phiên bản mới cần để parse/encode bản dump JSON của Twitter hay không
Bài viết về chủ đề này rất dễ hiểu, khiến người đọc muốn benchmark và tối ưu mã Ruby
Một bài viết và công trình rất tuyệt vời
Một bài viết rất thú vị
Rất thích công việc của byroot
Lời khuyên về C profiler rất hay
Mẹo hiệu năng "lookup table" được dùng trong PR của Mame rất ấn tượng
String#each_codepointthay vìString#each_charcó thể giảm gánh nặng cho GCChia sẻ một ví dụ giúp cải thiện hiệu năng hơn nữa trong codebase của mình
Array#packđể thu thập codepoint và chuyển thànhStringTrên CPU hiện đại, gợi ý dự đoán nhánh không còn hữu ích
Tò mò liệu Ruby JSON có dùng intrinsic hay không