Sự khác biệt giữa hai là gì? Ý tôi là tất cả các phương pháp đều giống nhau. Vì vậy, đối với người dùng, chúng hoạt động giống hệt nhau.
Đúng không??
Câu trả lời:
Từ bản tóm tắt SGI STL (có ngày nhưng vẫn rất hữu ích) về deque
:
Một deque rất giống một vectơ: giống như vectơ, nó là một chuỗi hỗ trợ truy cập ngẫu nhiên vào các phần tử, chèn thời gian không đổi và loại bỏ các phần tử ở cuối dãy, chèn và loại bỏ thời gian tuyến tính các phần tử ở giữa.
Cách chính mà deque khác với vector là deque cũng hỗ trợ chèn thời gian không đổi và loại bỏ các phần tử ở đầu dãy. Ngoài ra, deque không có bất kỳ hàm thành viên nào tương tự với dung lượng () và dự trữ () của vectơ, và không cung cấp bất kỳ đảm bảo nào về tính hợp lệ của trình lặp được liên kết với các hàm thành viên đó.
Đây là bản tóm tắt list
từ cùng một trang web:
Một danh sách là một danh sách được liên kết kép. Có nghĩa là, nó là một Trình tự hỗ trợ cả chuyển tiếp và duyệt ngược, và (phân bổ) theo thời gian không đổi và loại bỏ các phần tử ở đầu hoặc cuối, hoặc ở giữa. Danh sách có thuộc tính quan trọng là việc chèn và nối không làm mất hiệu lực các trình vòng lặp để liệt kê các phần tử và thậm chí việc loại bỏ chỉ làm mất hiệu lực các trình vòng lặp trỏ đến các phần tử bị loại bỏ. Thứ tự của các trình vòng lặp có thể được thay đổi (nghĩa là, danh sách :: trình vòng lặp có thể có một người tiền nhiệm hoặc người kế nhiệm khác sau một thao tác với danh sách so với trước đó), nhưng bản thân các trình vòng lặp sẽ không bị vô hiệu hoặc được thực hiện để trỏ đến các phần tử khác trừ khi sự vô hiệu hóa đó hoặc đột biến là rõ ràng.
Tóm lại, các vùng chứa có thể có các quy trình được chia sẻ nhưng thời gian đảm bảo cho các quy trình đó khác nhau giữa các vùng chứa . Điều này rất quan trọng khi xem xét vùng chứa nào trong số những vùng chứa này sẽ sử dụng cho một tác vụ: tính đến cách vùng chứa sẽ được sử dụng thường xuyên nhất (ví dụ: nhiều hơn để tìm kiếm hơn là chèn / xóa) sẽ giúp bạn hướng bạn đến đúng vùng chứa .
Hãy để tôi liệt kê những điểm khác biệt:
Phức tạp
Insert/erase at the beginning in middle at the end
Deque: Amortized constant Linear Amortized constant
List: Constant Constant Constant
constant
và là amortized constant
gì?
std::list
về cơ bản là một danh sách được liên kết kép.
std::deque
, mặt khác, được thực hiện giống như std::vector
. Nó có thời gian truy cập liên tục theo chỉ mục, cũng như chèn và xóa ở đầu và cuối, cung cấp các đặc điểm hiệu suất khác biệt đáng kể so với danh sách.
Một đảm bảo quan trọng khác là cách mỗi vùng chứa khác nhau lưu trữ dữ liệu của nó trong bộ nhớ:
Lưu ý rằng deque được thiết kế để cố gắng cân bằng các ưu điểm của cả vector và list mà không có nhược điểm tương ứng của chúng. Nó là một vùng chứa đặc biệt thú vị trong các nền tảng giới hạn bộ nhớ, ví dụ, vi điều khiển.
Tuy nhiên, chiến lược lưu trữ bộ nhớ thường bị bỏ qua, tuy nhiên, đây thường là một trong những lý do quan trọng nhất để chọn vùng chứa phù hợp nhất cho một ứng dụng nhất định.
Không. Một deque chỉ hỗ trợ chèn và xóa O (1) ở mặt trước và mặt sau. Ví dụ, nó có thể được triển khai trong một vectơ có bao bọc. Vì nó cũng đảm bảo O (1) truy cập ngẫu nhiên, bạn có thể chắc chắn rằng nó không sử dụng (chỉ) một danh sách được liên kết kép.
Những khác biệt về hiệu suất đã được giải thích bởi những người khác. Tôi chỉ muốn nói thêm rằng các giao diện tương tự hoặc thậm chí giống hệt nhau rất phổ biến trong lập trình hướng đối tượng - một phần của phương pháp luận chung để viết phần mềm hướng đối tượng. Bạn KHÔNG THỂ NÀO cho rằng hai lớp hoạt động giống nhau chỉ đơn giản là vì chúng triển khai cùng một giao diện, hơn nữa bạn nên giả định rằng một con ngựa hoạt động như một con chó vì cả hai đều thực hiện tấn công () và make_noise ().
Đây là cách sử dụng mã bằng chứng về khái niệm của danh sách, bản đồ không có thứ tự giúp tra cứu O (1) và duy trì LRU chính xác của O (1). Cần các trình vòng lặp (không bị xóa) để tồn tại các thao tác xóa. Lên kế hoạch sử dụng bộ nhớ đệm được quản lý bằng phần mềm lớn tùy ý O (1) cho con trỏ CPU trên bộ nhớ GPU. Bắt đầu với bộ lập lịch Linux O (1) (hàng đợi chạy LRU <-> trên mỗi bộ xử lý). Bản đồ không có thứ tự có quyền truy cập thời gian liên tục thông qua bảng băm.
#include <iostream>
#include <list>
#include <unordered_map>
using namespace std;
struct MapEntry {
list<uint64_t>::iterator LRU_entry;
uint64_t CpuPtr;
};
typedef unordered_map<uint64_t,MapEntry> Table;
typedef list<uint64_t> FIFO;
FIFO LRU; // LRU list at a given priority
Table DeviceBuffer; // Table of device buffers
void Print(void){
for (FIFO::iterator l = LRU.begin(); l != LRU.end(); l++) {
std::cout<< "LRU entry "<< *l << " : " ;
std::cout<< "Buffer entry "<< DeviceBuffer[*l].CpuPtr <<endl;
}
}
int main()
{
LRU.push_back(0);
LRU.push_back(1);
LRU.push_back(2);
LRU.push_back(3);
LRU.push_back(4);
for (FIFO::iterator i = LRU.begin(); i != LRU.end(); i++) {
MapEntry ME = { i, *i};
DeviceBuffer[*i] = ME;
}
std::cout<< "************ Initial set of CpuPtrs" <<endl;
Print();
{
// Suppose evict an entry - find it via "key - memory address uin64_t" and remove from
// cache "tag" table AND LRU list with O(1) operations
uint64_t key=2;
LRU.erase(DeviceBuffer[2].LRU_entry);
DeviceBuffer.erase(2);
}
std::cout<< "************ Remove item 2 " <<endl;
Print();
{
// Insert a new allocation in both tag table, and LRU ordering wiith O(1) operations
uint64_t key=9;
LRU.push_front(key);
MapEntry ME = { LRU.begin(), key };
DeviceBuffer[key]=ME;
}
std::cout<< "************ Add item 9 " <<endl;
Print();
std::cout << "Victim "<<LRU.back()<<endl;
}
Trong số những khác biệt nổi bật giữa deque
vàlist
Đối với deque
:
Các mặt hàng được lưu trữ cạnh nhau;
Tối ưu hóa để thêm dữ liệu từ hai phía (trước, sau);
Các phần tử được lập chỉ mục bởi số (số nguyên).
Có thể được duyệt bằng trình vòng lặp và thậm chí bằng chỉ mục của phần tử.
Thời gian truy cập dữ liệu nhanh hơn.
Đối với list
Các mục được lưu trữ "ngẫu nhiên" trong bộ nhớ;
Chỉ có thể được duyệt bởi trình lặp;
Tối ưu hóa cho việc chèn và loại bỏ ở giữa.
Thời gian truy cập dữ liệu chậm hơn, chậm lặp lại do tính định vị không gian rất kém.
Xử lý rất tốt các yếu tố lớn
Bạn cũng có thể kiểm tra Liên kết sau , này so sánh hiệu suất giữa hai vùng chứa STL (với std :: vector)
Hy vọng tôi đã chia sẻ một số thông tin hữu ích.