Q

Quản trị viên

Là một lập trình viên yêu công nghệ, thích viết blog để chia sẻ kiến thức, kinh nghiệm lập trình và những điều thú vị trong thế giới tech.

2301 bài viết · Website
Giải thuật 03/09/2026 8 phút

Cùng một hàm: -O0 tràn ngăn xếp ở 1 triệu, -O2 chạy tới 100 triệu

Đệ quy đuôi được đồn là liều thuốc chống tràn ngăn xếp. Nhưng cùng một hàm: gcc -O0 tràn ở 1 triệu tầng, gcc -O2 chạy 100 triệu vì biến thành vòng lặp, còn CPython không bao giờ tối ưu đuôi — vẫn tràn ở 1000 khung. 'Đệ quy đuôi an toàn' chỉ đúng khi trình biên dịch thật sự làm TCO. Tôi đo.

Giải thuật 03/09/2026 8 phút

Bỏ if cho nhanh: mẹo hay hay giáo điều?

Code không nhánh (branchless) luôn nhanh hơn if? Đo trên host ARM: khi nhánh khó đoán (dữ liệu ngẫu nhiên), branchless nhanh gấp 3 lần vì né được dự đoán sai. Nhưng khi nhánh dễ đoán và thân điều kiện rất đắt (8 phép chia, hiếm khi chạy), bản có if lại thắng vì bỏ qua được việc đắt. Và nhiều khi trình biên dịch đã tự bỏ nhánh giúp bạn rồi mà không hay.

Cơ sở dữ liệu 03/09/2026 9 phút

Merge join: 77ms khi dữ liệu đã sắp, 160ms khi phải tự sắp — và vì sao đừng vội chê nó thua hash

Merge join trên khóa đã sắp: 77ms không cần sort; nhưng trên cột chưa sắp phải thêm Sort tràn đĩa, 160ms (hash chỉ 78ms). Tôi suýt kết luận 'merge dở hơn hash' — cho tới khi thấy mình đo nó ở đúng điều kiện bất lợi. Đổi lại nó giữ nguyên thứ tự: ORDER BY LIMIT nhanh 0,03ms so với 72ms của hash.

Giải thuật 03/09/2026 9 phút

Tạo một luồng tốn 47µs, fork một tiến trình chỉ 82µs: cả hai niềm tin thường gặp đều sai

Tưởng tạo luồng gần như miễn phí, còn fork đắt gấp trăm lần vì phải nhân đôi cả bộ nhớ? Tôi đo: tạo+join một luồng rỗng mất ~47µs (không hề miễn phí), fork+waitpid ~82µs — fork chỉ 1,8 lần thread nhờ copy-on-write. Cả hai đều tốn hàng chục micro giây, và đó là lý do có thread pool.