about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorSteve Klabnik <steve@steveklabnik.com>2015-01-22 18:09:58 -0500
committerSteve Klabnik <steve@steveklabnik.com>2015-01-22 18:09:58 -0500
commit4db64bd82426fd914f98059e3fb7a146ed57ad9c (patch)
treead1ef659671f2f6385cf3bf5c0d49480e927cf1b /src/libstd
parentc76ce8c36cf39ee8036401a95c583dda8f0f38d6 (diff)
parent3819c222a84a9c21992b81939420643c0a969e7d (diff)
downloadrust-4db64bd82426fd914f98059e3fb7a146ed57ad9c.tar.gz
rust-4db64bd82426fd914f98059e3fb7a146ed57ad9c.zip
Rollup merge of #21217 - Gankro:docadoca, r=steveklabnik
Not sure on what *exactly* should be said here, but I think this is the most important bit. This PR also establishes conventions for describing performance minimally.

I suggest to describe preformance for individual methods we use a `# Performance` heading. Not sure if we should have 

```
# Performance: O(1)
details details
```
or

```
# Performance:
O(1)
details details
```

Since I think most methods don't need discussion, the former seems more resonable. But it's kind of weird to have info "in" the heading.

r? @steveklabnik 
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/collections/mod.rs54
1 files changed, 52 insertions, 2 deletions
diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs
index f085fd259de..21bea5dcdcb 100644
--- a/src/libstd/collections/mod.rs
+++ b/src/libstd/collections/mod.rs
@@ -49,8 +49,8 @@
 //! * You want a double-ended queue (deque).
 //!
 //! ### Use a `DList` when:
-//! * You want a `Vec` or `RingBuf` of unknown size, and can't tolerate inconsistent
-//! performance during insertions.
+//! * You want a `Vec` or `RingBuf` of unknown size, and can't tolerate amortization.
+//! * You want to efficiently split and append lists.
 //! * You are *absolutely* certain you *really*, *truly*, want a doubly linked list.
 //!
 //! ### Use a `HashMap` when:
@@ -85,6 +85,56 @@
 //! or "most important" one at any given time.
 //! * You want a priority queue.
 //!
+//! # Performance
+//!
+//! Choosing the right collection for the job requires an understanding of what each collection
+//! is good at. Here we briefly summarize the performance of different collections for certain
+//! important operations. For further details, see each type's documentation.
+//!
+//! Throughout the documentation, we will follow a few conventions. For all operations,
+//! the collection's size is denoted by n. If another collection is involved in the operation, it
+//! contains m elements. Operations which have an *amortized* cost are suffixed with a `*`.
+//! Operations with an *expected* cost are suffixed with a `~`.
+//!
+//! All amortized costs are for the potential need to resize when capacity is exhausted.
+//! If a resize occurs it will take O(n) time. Our collections never automatically shrink,
+//! so removal operations aren't amortized. Over a sufficiently large series of
+//! operations, the average cost per operation will deterministically equal the given cost.
+//!
+//! Only HashMap has expected costs, due to the probabilistic nature of hashing. It is
+//! theoretically possible, though very unlikely, for HashMap to experience worse performance.
+//!
+//! ## Sequences
+//!
+//! |         | get(i)         | insert(i)       | remove(i)      | append | split_off(i)   |
+//! |---------|----------------|-----------------|----------------|--------|----------------|
+//! | Vec     | O(1)           | O(n-i)*         | O(n-i)         | O(m)*  | O(n-i)         |
+//! | RingBuf | O(1)           | O(min(i, n-i))* | O(min(i, n-i)) | O(m)*  | O(min(i, n-i)) |
+//! | DList   | O(min(i, n-i)) | O(min(i, n-i))  | O(min(i, n-i)) | O(1)   | O(min(i, n-i)) |
+//! | Bitv    | O(1)           | O(n-i)*         | O(n-i)         | O(m)*  | O(n-i)         |
+//!
+//! Note that where ties occur, Vec is generally going to be faster than RingBuf, and RingBuf
+//! is generally going to be faster than DList. Bitv is not a general purpose collection, and
+//! therefore cannot reasonably be compared.
+//!
+//! ## Maps
+//!
+//! For Sets, all operations have the cost of the equivalent Map operation. For BitvSet,
+//! refer to VecMap.
+//!
+//! |          | get       | insert   | remove   | predecessor |
+//! |----------|-----------|----------|----------|-------------|
+//! | HashMap  | O(1)~     | O(1)~*   | O(1)~    | N/A         |
+//! | BTreeMap | O(log n)  | O(log n) | O(log n) | O(log n)    |
+//! | VecMap   | O(1)      | O(1)?    | O(1)     | O(n)        |
+//!
+//! Note that VecMap is *incredibly* inefficient in terms of space. The O(1) insertion time
+//! assumes space for the element is already allocated. Otherwise, a large key may require a
+//! massive reallocation, with no direct relation to the number of elements in the collection.
+//! VecMap should only be seriously considered for small keys.
+//!
+//! Note also that BTreeMap's precise preformance depends on the value of B.
+//!
 //! # Correct and Efficient Usage of Collections
 //!
 //! Of course, knowing which collection is the right one for the job doesn't instantly