[stdlib] Update complexity docs for seq/collection algorithms (#17254)

* [stdlib] Update complexity docs for seq/collection algorithms

This corrects and standardizes the complexity documentation for Sequence
and Collection methods. The use of constants is more consistent, with `n`
equal to the length of the target collection, `m` equal to the length of
a collection passed in as a parameter, and `k` equal to any other passed
or calculated constant.

* Apply notes from @brentdax about complexity nomenclature

* Change `n` to `distance` in `index(_:offsetBy:)`

* Use equivalency language more places; sync across array types

* Use k instead of n for parameter names

* Slight changes to index(_:offsetBy:) discussion.

* Update tests with new parameter names
This commit is contained in:
Nate Cook
2018-07-24 01:01:34 -05:00
committed by GitHub
parent 0abb019ddf
commit 3d7dfc232b
16 changed files with 551 additions and 392 deletions

View File

@@ -61,6 +61,8 @@ extension Sequence {
/// // Prints "Mateo"
///
/// - Returns: A sequence of pairs enumerating the sequence.
///
/// - Complexity: O(1)
@inlinable // protocol-only
public func enumerated() -> EnumeratedSequence<Self> {
return EnumeratedSequence(_base: self)
@@ -102,6 +104,8 @@ extension Sequence {
/// - Returns: The sequence's minimum element, according to
/// `areInIncreasingOrder`. If the sequence has no elements, returns
/// `nil`.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable // protocol-only
@warn_unqualified_access
public func min(
@@ -144,6 +148,8 @@ extension Sequence {
/// otherwise, `false`.
/// - Returns: The sequence's maximum element if the sequence is not empty;
/// otherwise, `nil`.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable // protocol-only
@warn_unqualified_access
public func max(
@@ -170,6 +176,8 @@ extension Sequence where Element: Comparable {
///
/// - Returns: The sequence's minimum element. If the sequence has no
/// elements, returns `nil`.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable
@warn_unqualified_access
public func min() -> Element? {
@@ -187,6 +195,8 @@ extension Sequence where Element: Comparable {
///
/// - Returns: The sequence's maximum element. If the sequence has no
/// elements, returns `nil`.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable
@warn_unqualified_access
public func max() -> Element? {
@@ -219,6 +229,9 @@ extension Sequence {
/// - Returns: `true` if the initial elements of the sequence are equivalent
/// to the elements of `possiblePrefix`; otherwise, `false`. If
/// `possiblePrefix` has no elements, the return value is `true`.
///
/// - Complexity: O(*m*), where *m* is the lesser of the length of the
/// sequence and the length of `possiblePrefix`.
@inlinable
public func starts<PossiblePrefix: Sequence>(
with possiblePrefix: PossiblePrefix,
@@ -262,6 +275,9 @@ extension Sequence where Element: Equatable {
/// - Returns: `true` if the initial elements of the sequence are the same as
/// the elements of `possiblePrefix`; otherwise, `false`. If
/// `possiblePrefix` has no elements, the return value is `true`.
///
/// - Complexity: O(*m*), where *m* is the lesser of the length of the
/// sequence and the length of `possiblePrefix`.
@inlinable
public func starts<PossiblePrefix: Sequence>(
with possiblePrefix: PossiblePrefix
@@ -296,6 +312,9 @@ extension Sequence {
/// are equivalent; otherwise, `false`.
/// - Returns: `true` if this sequence and `other` contain equivalent items,
/// using `areEquivalent` as the equivalence test; otherwise, `false.`
///
/// - Complexity: O(*m*), where *m* is the lesser of the length of the
/// sequence and the length of `other`.
@inlinable
public func elementsEqual<OtherSequence: Sequence>(
_ other: OtherSequence,
@@ -336,6 +355,9 @@ extension Sequence where Element : Equatable {
/// - Parameter other: A sequence to compare to this sequence.
/// - Returns: `true` if this sequence and `other` contain the same elements
/// in the same order.
///
/// - Complexity: O(*m*), where *m* is the lesser of the length of the
/// sequence and the length of `other`.
@inlinable
public func elementsEqual<OtherSequence: Sequence>(
_ other: OtherSequence
@@ -378,6 +400,9 @@ extension Sequence {
/// ordering, which has no connection to Unicode. If you are sorting
/// strings to present to the end user, use `String` APIs that perform
/// localized comparison instead.
///
/// - Complexity: O(*m*), where *m* is the lesser of the length of the
/// sequence and the length of `other`.
@inlinable
public func lexicographicallyPrecedes<OtherSequence: Sequence>(
_ other: OtherSequence,
@@ -429,6 +454,9 @@ extension Sequence where Element : Comparable {
/// ordering, which has no connection to Unicode. If you are sorting
/// strings to present to the end user, use `String` APIs that
/// perform localized comparison.
///
/// - Complexity: O(*m*), where *m* is the lesser of the length of the
/// sequence and the length of `other`.
@inlinable
public func lexicographicallyPrecedes<OtherSequence: Sequence>(
_ other: OtherSequence
@@ -477,6 +505,8 @@ extension Sequence {
/// the passed element represents a match.
/// - Returns: `true` if the sequence contains an element that satisfies
/// `predicate`; otherwise, `false`.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable
public func contains(
where predicate: (Element) throws -> Bool
@@ -504,6 +534,8 @@ extension Sequence {
/// the passed element satisfies a condition.
/// - Returns: `true` if the sequence contains only elements that satisfy
/// `predicate`; otherwise, `false`.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable
public func allSatisfy(
_ predicate: (Element) throws -> Bool
@@ -528,6 +560,8 @@ extension Sequence where Element : Equatable {
/// - Parameter element: The element to find in the sequence.
/// - Returns: `true` if the element was found in the sequence; otherwise,
/// `false`.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable
public func contains(_ element: Element) -> Bool {
if let result = _customContainsEquatableElement(element) {
@@ -584,6 +618,8 @@ extension Sequence {
/// the caller.
/// - Returns: The final accumulated value. If the sequence has no elements,
/// the result is `initialResult`.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable
public func reduce<Result>(
_ initialResult: Result,
@@ -639,6 +675,8 @@ extension Sequence {
/// value with an element of the sequence.
/// - Returns: The final accumulated value. If the sequence has no elements,
/// the result is `initialResult`.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable
public func reduce<Result>(
into initialResult: Result,
@@ -663,10 +701,10 @@ extension Sequence {
///
/// The sequence must be finite.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
///
/// - Returns: An array containing the elements of this sequence in
/// reverse order.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable
public func reversed() -> [Element] {
// FIXME(performance): optimize to 1 pass? But Array(self) can be
@@ -710,8 +748,8 @@ extension Sequence {
/// sequence as its argument and returns a sequence or collection.
/// - Returns: The resulting flattened array.
///
/// - Complexity: O(*m* + *n*), where *m* is the length of this sequence
/// and *n* is the length of the result.
/// - Complexity: O(*m* + *n*), where *n* is the length of this sequence
/// and *m* is the length of the result.
@inlinable
public func flatMap<SegmentOfResult : Sequence>(
_ transform: (Element) throws -> SegmentOfResult
@@ -747,8 +785,8 @@ extension Sequence {
/// - Returns: An array of the non-`nil` results of calling `transform`
/// with each element of the sequence.
///
/// - Complexity: O(*m* + *n*), where *m* is the length of this sequence
/// and *n* is the length of the result.
/// - Complexity: O(*m* + *n*), where *n* is the length of this sequence
/// and *m* is the length of the result.
@inlinable // protocol-only
public func compactMap<ElementOfResult>(
_ transform: (Element) throws -> ElementOfResult?