|
49 | 49 | //! * You want a double-ended queue (deque).
|
50 | 50 | //!
|
51 | 51 | //! ### Use a `DList` when:
|
52 |
| -//! * You want a `Vec` or `RingBuf` of unknown size, and can't tolerate inconsistent |
53 |
| -//! performance during insertions. |
| 52 | +//! * You want a `Vec` or `RingBuf` of unknown size, and can't tolerate amortization. |
| 53 | +//! * You want to efficiently split and append lists. |
54 | 54 | //! * You are *absolutely* certain you *really*, *truly*, want a doubly linked list.
|
55 | 55 | //!
|
56 | 56 | //! ### Use a `HashMap` when:
|
|
85 | 85 | //! or "most important" one at any given time.
|
86 | 86 | //! * You want a priority queue.
|
87 | 87 | //!
|
| 88 | +//! # Performance |
| 89 | +//! |
| 90 | +//! Choosing the right collection for the job requires an understanding of what each collection |
| 91 | +//! is good at. Here we briefly summarize the performance of different collections for certain |
| 92 | +//! important operations. For further details, see each type's documentation. |
| 93 | +//! |
| 94 | +//! Throughout the documentation, we will follow a few conventions. For all operations, |
| 95 | +//! the collection's size is denoted by n. If another collection is involved in the operation, it |
| 96 | +//! contains m elements. Operations which have an *amortized* cost are suffixed with a `*`. |
| 97 | +//! Operations with an *expected* cost are suffixed with a `~`. |
| 98 | +//! |
| 99 | +//! All amortized costs are for the potential need to resize when capacity is exhausted. |
| 100 | +//! If a resize occurs it will take O(n) time. Our collections never automatically shrink, |
| 101 | +//! so removal operations aren't amortized. Over a sufficiently large series of |
| 102 | +//! operations, the average cost per operation will deterministically equal the given cost. |
| 103 | +//! |
| 104 | +//! Only HashMap has expected costs, due to the probabilistic nature of hashing. It is |
| 105 | +//! theoretically possible, though very unlikely, for HashMap to experience worse performance. |
| 106 | +//! |
| 107 | +//! ## Sequences |
| 108 | +//! |
| 109 | +//! | | get(i) | insert(i) | remove(i) | append | split_off(i) | |
| 110 | +//! |---------|----------------|-----------------|----------------|--------|----------------| |
| 111 | +//! | Vec | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) | |
| 112 | +//! | RingBuf | O(1) | O(min(i, n-i))* | O(min(i, n-i)) | O(m)* | O(min(i, n-i)) | |
| 113 | +//! | DList | O(min(i, n-i)) | O(min(i, n-i)) | O(min(i, n-i)) | O(1) | O(min(i, n-i)) | |
| 114 | +//! | Bitv | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) | |
| 115 | +//! |
| 116 | +//! Note that where ties occur, Vec is generally going to be faster than RingBuf, and RingBuf |
| 117 | +//! is generally going to be faster than DList. Bitv is not a general purpose collection, and |
| 118 | +//! therefore cannot reasonably be compared. |
| 119 | +//! |
| 120 | +//! ## Maps |
| 121 | +//! |
| 122 | +//! For Sets, all operations have the cost of the equivalent Map operation. For BitvSet, |
| 123 | +//! refer to VecMap. |
| 124 | +//! |
| 125 | +//! | | get | insert | remove | predecessor | |
| 126 | +//! |----------|-----------|----------|----------|-------------| |
| 127 | +//! | HashMap | O(1)~ | O(1)~* | O(1)~ | N/A | |
| 128 | +//! | BTreeMap | O(log n) | O(log n) | O(log n) | O(log n) | |
| 129 | +//! | VecMap | O(1) | O(1)? | O(1) | O(n) | |
| 130 | +//! |
| 131 | +//! Note that VecMap is *incredibly* inefficient in terms of space. The O(1) insertion time |
| 132 | +//! assumes space for the element is already allocated. Otherwise, a large key may require a |
| 133 | +//! massive reallocation, with no direct relation to the number of elements in the collection. |
| 134 | +//! VecMap should only be seriously considered for small keys. |
| 135 | +//! |
| 136 | +//! Note also that BTreeMap's precise preformance depends on the value of B. |
| 137 | +//! |
88 | 138 | //! # Correct and Efficient Usage of Collections
|
89 | 139 | //!
|
90 | 140 | //! Of course, knowing which collection is the right one for the job doesn't instantly
|
|
0 commit comments