Vì có vô số câu trả lời, bạn có thể nhầm lẫn, nhưng tóm lại:
Sử dụng a std::queue
. Lý do cho điều này rất đơn giản: nó là một cấu trúc FIFO. Bạn muốn FIFO, bạn sử dụng a std::queue
.
Nó làm cho ý định của bạn rõ ràng với bất kỳ ai khác, và ngay cả với chính bạn. A std::list
hoặc std::deque
không. Một danh sách có thể chèn và xóa ở bất kỳ đâu, đây không phải là điều mà cấu trúc FIFO được cho là làm và deque
có thể thêm và xóa từ một trong hai đầu, đây cũng là điều mà cấu trúc FIFO không thể làm được.
Đây là lý do tại sao bạn nên sử dụng a queue
.
Bây giờ, bạn đã hỏi về hiệu suất. Đầu tiên, hãy luôn nhớ quy tắc ngón tay cái quan trọng này: Mã tốt trước, hiệu suất sau cùng.
Lý do cho điều này rất đơn giản: những người phấn đấu để đạt được hiệu suất trước sự sạch sẽ và thanh lịch hầu như luôn về đích cuối cùng. Mã của họ trở thành một mớ hỗn độn, bởi vì họ đã từ bỏ tất cả những gì tốt đẹp để thực sự không nhận được gì từ nó.
Bằng cách viết mã tốt, dễ đọc trước, hầu hết các vấn đề về hiệu suất sẽ tự giải quyết. Và nếu sau đó, bạn thấy hiệu suất của mình bị thiếu, bây giờ bạn có thể dễ dàng thêm một bộ hồ sơ vào mã sạch đẹp của mình và tìm ra vấn đề ở đâu.
Điều đó đã nói tất cả, std::queue
chỉ là một bộ chuyển đổi. Nó cung cấp giao diện an toàn, nhưng sử dụng một vùng chứa khác ở bên trong. Bạn có thể chọn vùng chứa bên dưới này và điều này cho phép rất linh hoạt.
Vì vậy, bạn nên sử dụng vùng chứa bên dưới nào? Chúng ta biết rằng std::list
và std::deque
cả cung cấp các chức năng cần thiết ( push_back()
, pop_front()
và front()
), vì vậy làm thế nào để chúng tôi quyết định?
Trước tiên, hãy hiểu rằng phân bổ (và phân bổ) bộ nhớ nói chung không phải là một việc nhanh chóng để làm, bởi vì nó liên quan đến việc ra ngoài hệ điều hành và yêu cầu nó làm một việc gì đó. A list
phải cấp phát bộ nhớ mỗi khi một cái gì đó được thêm vào và phân bổ nó khi nó biến mất.
A deque
, mặt khác, phân bổ theo khối. Nó sẽ phân bổ ít thường xuyên hơn a list
. Hãy coi nó như một danh sách, nhưng mỗi đoạn bộ nhớ có thể chứa nhiều nút. (Tất nhiên, tôi khuyên bạn nên thực sự tìm hiểu cách hoạt động của nó .)
Vì vậy, chỉ với điều đó một mình deque
sẽ hoạt động tốt hơn, bởi vì nó không liên quan đến bộ nhớ thường xuyên. Kết hợp với thực tế là bạn đang xử lý dữ liệu có kích thước không đổi, nó có thể sẽ không phải phân bổ sau lần đầu tiên chuyển qua dữ liệu, trong khi một danh sách sẽ liên tục phân bổ và phân bổ.
Điều thứ hai cần hiểu là hiệu suất bộ nhớ cache . Việc sử dụng RAM rất chậm, vì vậy khi CPU thực sự cần, nó sẽ tận dụng tối đa khoảng thời gian này bằng cách lấy lại một phần bộ nhớ vào bộ nhớ đệm. Vì một deque
phân bổ trong các khối bộ nhớ, có khả năng việc truy cập một phần tử trong vùng chứa này cũng sẽ khiến CPU đưa phần còn lại của vùng chứa trở lại. Giờ đây, bất kỳ truy cập nào tiếp theo vào deque
sẽ diễn ra nhanh chóng, bởi vì dữ liệu nằm trong bộ nhớ cache.
Điều này không giống như một danh sách, nơi dữ liệu được phân bổ từng lần một. Điều này có nghĩa là dữ liệu có thể được dàn trải khắp nơi trong bộ nhớ và hiệu suất bộ nhớ cache sẽ kém.
Vì vậy, xét rằng, a deque
nên là một lựa chọn tốt hơn. Đây là lý do tại sao nó là vùng chứa mặc định khi sử dụng a queue
. Điều đó đã nói lên tất cả, đây vẫn chỉ là một phỏng đoán (rất) được giáo dục: bạn sẽ phải lập hồ sơ mã này, sử dụng một deque
trong một bài kiểm tra và list
trong một bài kiểm tra khác để thực sự biết chắc chắn.
Nhưng hãy nhớ: để mã hoạt động với giao diện sạch sẽ, sau đó lo lắng về hiệu suất.
John lo ngại rằng việc bao bọc một list
hoặc deque
sẽ làm giảm hiệu suất. Một lần nữa, anh ấy và tôi có thể nói chắc chắn mà không cần tự mình lược tả nó, nhưng rất có thể là trình biên dịch sẽ nội tuyến các lệnh gọi mà nó queue
thực hiện. Có nghĩa là, khi bạn nói queue.push()
, nó thực sự sẽ chỉ nói queue.container.push_back()
, bỏ qua hoàn toàn lệnh gọi hàm.
Một lần nữa, đây chỉ là một phỏng đoán có học thức, nhưng sử dụng một queue
sẽ không làm giảm hiệu suất, khi so sánh với việc sử dụng nguyên container bên dưới. Như tôi đã nói trước đây, hãy sử dụng queue
, bởi vì nó sạch sẽ, dễ sử dụng và an toàn, và nếu nó thực sự trở thành một hồ sơ vấn đề và thử nghiệm.