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

Benchmark của tôi đo ra 0 nano giây, rồi 4,62 ms, rồi vọt 2,7 lần — bốn cách cái đồng hồ nói dối

Kẹp đồng hồ hai đầu vòng lặp rồi đọc số nghe đơn giản, nhưng con số ấy nói dối bốn kiểu: bỏ sink thì compiler xóa vòng và đo ra 0 ns cho việc chưa chạy; lần đầu chậm 27% vì cache lạnh; trên VM một lần vọt 2,7 lần median; và clock_gettime tốn 16 ns nên đo việc vài ns ra rác. Cách đo cho đáng tin.

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

Đặt một bit khi thì chậm hơn ghi byte, khi thì nhanh gấp 6 — cùng một dòng code

Bitset nhỏ hơn mảng bool 8 lần, giao hai tập bằng AND nhanh 12,9 lần (64 phần tử mỗi lệnh). Nhưng đặt một bit lẻ chậm hơn ghi một byte 1,46 lần khi vừa cache — rồi nhanh hơn 6,3 lần khi tràn cache. Lợi thật của bitset là mật độ cache, không phải mẹo bit. Tôi đo cả đường cong.

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

Dijkstra trả về 4 khi đáp án đúng là 2 — chỉ vì một cạnh mang dấu trừ

Dijkstra là thuật toán tham lam nhưng đúng — nhờ đúng một điều kiện: trọng số không âm. Cho nó một cạnh âm (2→1 = -3), nó chốt dist[1]=4 sai trong khi đáp án thật là 2, mà không một cảnh báo. Và cấu trúc bên trong quyết định quy mô: heap nhanh hơn mảng 36 lần trên đồ thị thưa. Tôi đo.

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

'Thêm phần tử là O(1)' — vậy sao có một lần nó ngốn 392 micro giây?

Thêm vào mảng động là O(1) khấu hao, nhưng đo đường cong từng thao tác thấy gai O(n): lần cấp phát cuối sao chép 2,1 triệu phần tử mất 392µs, gấp 400.000 lần một lần thêm thường. Và tăng dung lượng mỗi lần +1 để 'tiết kiệm bộ nhớ' hóa ra là O(n²), chậm 17.851 lần. Tôi đo cả đường cong.

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

Một dòng tung xúc xắc cắt 2 tỉ phép so sánh xuống còn 1,3 triệu

Quicksort pivot cố định gặp mảng đã sắp xếp làm 2,05 tỉ so sánh (901 ms); pivot ngẫu nhiên chỉ 1,3 triệu (1,1 ms) — ít hơn 1524 lần. Và skip list cân bằng bằng tung đồng xu, đạt ~log n mà không một phép xoay. Gieo ngẫu nhiên đúng chỗ là tăng an toàn, không phải thêm rủi ro. Tôi đo.