Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a section on performance to collection docs #21217

Merged
merged 1 commit into from
Jan 23, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 52 additions & 2 deletions src/libstd/collections/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should probably have graves around the 'n'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I wasn't sure about this. Ideally I would use mathmode, but we don't support it. Making all the math codemode is a bit weird looking.

  • O(min(i, n-i))
  • O(min(i, n-i))
  • O(min(i, n-i))
  • O(min(i, n-i))

//! contains m elements. Operations which have an *amortized* cost are suffixed with a `*`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same with m

//! 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
Expand Down