- Trong lúc đọc các bài báo để tối ưu hiệu năng, tôi lần đầu tiếp cận khái niệm Succinct Data Structures (cấu trúc dữ liệu súc tích)
- Khi tìm các bài báo liên quan, tôi đã trực tiếp trao đổi với giáo sư Gonzalo Navarro, một nhà nghiên cứu nổi tiếng trong lĩnh vực này
- Khác với mảng, hash map, cây và các cấu trúc quen thuộc khác, tôi bắt đầu tự hỏi vì sao những cấu trúc dữ liệu này lại chưa được sử dụng rộng rãi
- Vì vậy tôi muốn giải thích ngắn gọn về chủ đề này
Tổng quan về Succinct Data Structures
- Tương tự như nén dữ liệu thông thường, dữ liệu được lưu ở dạng nén, nhưng vẫn có thể được sử dụng trực tiếp ngay trong trạng thái đã nén
- Điểm khác với cách nén truyền thống: có thể truy cập và thao tác dữ liệu mà không cần giải nén
- Đây là một lĩnh vực đã được nghiên cứu rất sôi nổi trong 25 năm gần đây
Ứng dụng trong Rust
- Trong lập trình hệ thống, hiệu năng và mức dùng bộ nhớ rất quan trọng, nên những cấu trúc dữ liệu này có tiềm năng đặc biệt hữu ích
- Các nghiên cứu trước đây chủ yếu được thực hiện bằng C++, nhưng hiện nay cũng đã bắt đầu xuất hiện các bản triển khai trong Rust
- Bài viết giới thiệu một số thư viện có thể hữu ích cho các lập trình viên Rust
Bit Vectors (vector bit)
- Ví dụ mảng bit:
[0, 1, 0, 1, 1, 0, 1, 0]
- Trên hệ thống 64 bit, có thể lưu 64 bit trong một số nguyên duy nhất, nhờ đó tiết kiệm không gian
- Bản thân vector bit không phải là một cấu trúc succinct, nhưng có những cách khai thác nó hiệu quả
Rank/Select Bit Vector
- Phép toán Rank: tính xem trước một chỉ mục nhất định đã xuất hiện bao nhiêu bit
1
- Phép toán Select: trả về vị trí xuất hiện của bit
1 thứ n
- Có thể thực thi với độ phức tạp thời gian O(1)
- Overhead bộ nhớ thấp, rất hữu ích khi xử lý chuỗi lớn
- Trường hợp sử dụng
- Hữu ích khi lưu trữ một chuỗi lớn dưới dạng các chuỗi con nhỏ hơn
- Có thể tìm hiệu quả xem một chỉ mục cụ thể thuộc về chuỗi con nào
- Nhờ cách lưu trữ nén, có thể giảm mức dùng bộ nhớ mà vẫn tìm kiếm nhanh
- Thư viện Rust
vers: cung cấp hiệu năng cao và overhead tối thiểu
sucds: hỗ trợ các triển khai thưa (sparse) như SArray
vers có thế mạnh ở việc xây dựng cấu trúc dữ liệu hiệu quả, và dự kiến sẽ hỗ trợ cả triển khai thưa trong tương lai
Wavelet Matrix (ma trận wavelet)
- Mở rộng khái niệm Rank/Select sang dữ liệu có bảng chữ cái lớn hơn
- Ví dụ: phân tích chuỗi DNA (A, C, G, T) hoặc tìm kiếm văn bản (ký tự UTF-8, 256 ký hiệu)
- Hoạt động dựa trên Rank/Select bit vector
- Thư viện Rust
vers có bao gồm triển khai ma trận wavelet
FM-Index (chỉ mục chuỗi nén)
- Lưu trữ lượng lớn dữ liệu văn bản ở dạng nén đồng thời vẫn hỗ trợ chức năng tìm kiếm
- Các chức năng cốt lõi:
count(pattern): tính số lần xuất hiện của một mẫu cụ thể (chuỗi)
locate(pattern): trả về tất cả các chỉ mục nơi mẫu đó xuất hiện
- Hữu ích trong tìm kiếm chuỗi DNA và tìm kiếm văn bản quy mô lớn
- Thư viện Rust
- Có thể sử dụng thư viện
fm-index
- Trước đây dùng
fid, nhưng sau khi chuyển sang vers thì hiệu năng đã được cải thiện
Balanced Parentheses (biểu diễn ngoặc cân bằng)
- Nén và lưu trữ cấu trúc cây ở mức 2 bit cho mỗi nút
- Cây ví dụ:
a
/ \
b c
- Có thể biểu diễn dưới dạng
(()())
- Có thể chuyển thành
1 (ngoặc mở) và 0 (ngoặc đóng): 110100
- Tận dụng phép toán Rank/Select để tối ưu các thao tác duyệt trong cây
- Thư viện Rust
- Đang được triển khai trên nhánh
dev-bp của vers
Ứng dụng: lưu trữ và xử lý XML
- Có thể lưu XML bằng cách dùng biểu diễn ngoặc cân bằng
- Để xử lý hiệu quả các thẻ XML (
p, div v.v.), có thể dùng Rank/Select bit vector
- Dùng
FM-Index để cải thiện hiệu năng tìm kiếm văn bản
Kết luận
- Cấu trúc dữ liệu succinct đồng thời mang lại mức dùng bộ nhớ thấp và phép toán nhanh
- Dù đã có nhiều nghiên cứu trong C++, chúng cũng đang được hiện thực tích cực trong Rust
- Việc cộng tác với các nhà nghiên cứu và lập trình viên mã nguồn mở đã mở ra rất nhiều tiềm năng
- Nhiều khả năng chúng sẽ được sử dụng rộng rãi hơn trong nhiều lĩnh vực khoa học máy tính trong tương lai
2 bình luận
Cấu trúc nén sử dụng Wavelet đang được dùng rất tốt như một tiêu chuẩn trong Djvu. Khả năng nén ảnh thực sự rất xuất sắc.
Ý kiến trên Hacker News
Tôi đã gửi email cho Gonzalo Navarro để hỏi vài điều, và kết quả là cuối cùng chúng tôi đã cùng viết một bài báo
Tôi đã ở trong lĩnh vực này hơn 30 năm nhưng đây là lần đầu tiên tôi nghe đến "cấu trúc dữ liệu succinct"
Cấu trúc dữ liệu succinct có thể không nhanh hơn cấu trúc truyền thống khi tập dữ liệu vừa trong bộ nhớ
Tôi lần đầu nghe về khái niệm cấu trúc dữ liệu succinct từ Edward Kmett
Cấu trúc dữ liệu succinct rất thú vị
Cuốn sách của Navarro là một tài liệu khảo cứu rất xuất sắc
Tôi đã dành cả buổi sáng để tìm hiểu về cấu trúc dữ liệu succinct, và hiệu quả bộ nhớ của chúng thật đáng kinh ngạc
Có một cách để làm cho biểu diễn nút trong bộ nhớ của các struct lớn hiệu quả hơn
Marisa trie là một cấu trúc dữ liệu succinct rất ngầu và hữu ích
Thư viện nền tảng tôi dùng cho cấu trúc dữ liệu succinct là SDSL-Lite