Lập trình 07/11/2026 6 phút

Rust đo thật — Vec và capacity: lớn dần bằng cách nhân đôi sức chứa (0→4→8→…→2048), nên chèn 1025 phần tử chỉ cần ~10 lần cấp phát chứ không phải 1025; ép grow-by-1 thì chậm gấp 4 lần, còn with_capacity biết trước cỡ thì nhanh nhất

Phần 6 sê-ri Rust đo thật: Vec<T> là mảng động, và cách nó lớn lên quyết định hiệu năng. Đo trong container rust 1.99.1: mỗi khi hết chỗ, Vec NHÂN ĐÔI sức chứa (cap 0→4→8→16→…→2048), nên chèn 1025 phần tử chỉ cần ~10 lần cấp phát thay vì 1025 — mỗi push thành O(1) khấu hao. Thú vị: trong 10 lần đổi capacity, bộ cấp phát chỉ thật sự DỜI vùng nhớ 2 lần, còn lại nới khối tại chỗ. So ba chiến lược chèn 200.000 phần tử: nhân đôi mặc định 0,35 ms, grow-by-1 1,41 ms — chậm gấp 4 lần, with_capacity 0,34 ms. Biết trước số phần tử thì luôn dùng with_capacity.

Lập trình 06/11/2026 6 phút

Rust đo thật — Box, Rc, Arc: con trỏ thông minh và cái giá của việc đếm tham chiếu; Rc::clone chỉ +1 bộ đếm (2,47 ns) còn Arc dùng phép nguyên tử nên đắt gấp 1,5 lần (3,62 ns), và trình biên dịch chặn Rc qua luồng bằng E0277

Phần 5 sê-ri Rust đo thật: ba con trỏ thông minh và chi phí thật, đo trong container rust 1.99.1. Box<T> là sở hữu duy nhất trên heap — stack chỉ giữ 1 con trỏ 8 byte dù dữ liệu 1024 byte. Rc<T> cho nhiều chủ cùng sở hữu bằng đếm tham chiếu: Rc::clone KHÔNG sao chép dữ liệu, chỉ +1 bộ đếm (strong_count 1→2→3→2→1), mọi bản cùng địa chỉ heap. Arc<T> giống Rc nhưng đếm bằng phép nguyên tử để an toàn đa luồng — đo được cái giá: 100 triệu lần clone+drop, Rc mất 2,47 ns/lần còn Arc 3,62 ns/lần, chậm gấp 1,5 lần. Và trình biên dịch chặn dùng Rc qua luồng bằng lỗi E0277, buộc chọn đúng công cụ.

Lập trình 05/11/2026 6 phút

Rust đo thật — trừu tượng chi phí bằng không: chuỗi iterator filter.map.sum biên dịch ra ĐÚNG mã của vòng for viết tay (9,94 ms so với 10,44 ms, cùng 0 lệnh gọi hàm và 5 lệnh nhân), nhưng chỉ sau khi tối ưu — ở bản debug nó chậm gấp 2,1 lần

Phần 4 sê-ri Rust đo thật: trừu tượng chi phí bằng không nghĩa là iterator, closure, generic biên dịch ra mã nhanh ngang code viết tay — và đo được. Trong container rust 1.99.1, cùng bài toán tổng bình phương số chẵn trên 50 triệu phần tử: bản release, chuỗi v.iter().filter().map().sum() chạy 9,94 ms còn vòng for thủ công 10,44 ms — ngang nhau. Nhìn assembly aarch64: cả hai hàm đều 0 lệnh gọi hàm (closure bị nội tuyến sạch) và 5 lệnh nhân (mở cuộn y hệt). Nhưng bằng không chỉ đúng SAU tối ưu: ở bản debug, iterator chậm 246 ms so với 114 ms của vòng tay, gấp 2,1 lần.

Lập trình 04/11/2026 7 phút

Rust đo thật — bố cục bộ nhớ: trình biên dịch tự sắp lại trường để struct 15 byte dữ liệu chỉ tốn 16 byte thay vì 32 như repr(C), Option<&T> vẫn đúng 8 byte nhờ tối ưu niche, còn kiểu kích thước 0 không chiếm byte nào

Phần 3 sê-ri Rust đo thật: đo bằng size_of và align_of trong container rust 1.99.1 cách Rust xếp dữ liệu. Một struct chứa 15 byte dữ liệu thật nhưng xen kẽ u8/u64/u32: repr Rust mặc định thì trình biên dịch TỰ sắp lại trường, gói còn 16 byte; ép repr(C) giữ nguyên thứ tự khai báo thì phình lên 32 byte vì padding. Tối ưu niche: Option<&T> và Option<Box<T>> vẫn đúng 8 byte (dùng null làm None), Option<bool>=1, nhưng Option<u64>=16 vì u64 dùng hết mọi bit. Enum = biến thể lớn nhất cộng cờ phân biệt (24 byte). Kiểu kích thước 0 như () tốn 0 byte, Vec<()> không cấp phát heap.

Lập trình 03/11/2026 8 phút

Rust đo thật — borrow checker: mượn chia sẻ thì bất biến, &mut thì độc quyền; sửa vec khi đang duyệt hay cho &mut đụng một & đang sống đều là lỗi biên dịch E0502/E0499, còn trả tham chiếu tới biến cục bộ bị chặn ngay bằng E0515

Phần 2 sê-ri Rust đo thật: ta cần cho mượn giá trị mà không trao quyền sở hữu, và borrow checker áp đúng một luật — aliasing XOR mutability: nhiều tham chiếu chia sẻ & cùng lúc thì được, nhưng chỉ cần một &mut thì nó phải độc quyền. Đo trong container rust 1.99.1 bằng chính các lỗi biên dịch: &mut v khi một &v đang còn dùng cho E0502, hai &mut cùng lúc cho E0499, sửa vec giữa vòng for cho E0502 (chặn iterator invalidation — bug kinh điển của C++), trả tham chiếu tới biến cục bộ bị chặn bằng E0515. Nhờ non-lexical lifetime, push sau khi tham chiếu hết dùng vẫn biên dịch.

Lập trình 02/11/2026 8 phút

Rust đo thật — ownership và move: vì sao không cần bộ gom rác; dùng lại giá trị sau khi move là lỗi BIÊN DỊCH E0382, còn drop chạy xác định theo thứ tự ngược khai báo, quyết tại lúc biên dịch chứ không phải lúc chạy

Bài mở đầu sê-ri Rust đo thật: ownership là quy tắc mỗi giá trị có đúng một chủ, và khi hết phạm vi của chủ thì giá trị bị dọn ngay — không cần bộ gom rác, không cần free thủ công. Đo trong container rust 1.99.1: gán String cho biến khác là MOVE, dùng lại biến cũ cho ra lỗi biên dịch E0382 (chương trình không chạy nổi), move chỉ sao chép 3 word trên stack nên con trỏ heap giữ nguyên địa chỉ (0xaaaa...7d60 trước và sau), i32 là Copy nên vẫn dùng được cả hai, và hàm drop chạy đúng thứ tự ngược khai báo ngay tại cuối phạm vi — toàn bộ quyết định tại lúc biên dịch.