From e6fdc28d853a22b49bb65f72400d648c34f04bde Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jan 2026 17:30:14 +0100 Subject: [PATCH 01/17] Add time/space complexity remarks to Set type and module functions - Added complexity documentation to all 47 Set functions/members - Set type members: new O(n log n), Add/Remove/Contains O(log n), Count/IsEmpty O(1), Min/MaximumElement O(log n), set operations O(m log n), subset/superset O(n log m) - Set module functions: empty/singleton/isEmpty O(1), add/remove/contains O(log n), fold/iter/exists/forall O(n), filter/map/partition O(n log n), union/intersect/difference O(m log n), ofList/ofArray/ofSeq O(n log n), toList/toArray O(n), toSeq O(1) - Format: 'This is an O(...) operation, where n is...' - Build succeeds with 0 errors - XML validation test passes --- .gitignore | 3 ++ src/FSharp.Core/set.fsi | 94 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/.gitignore b/.gitignore index d9a2e5384de..4d8614da8fb 100644 --- a/.gitignore +++ b/.gitignore @@ -158,3 +158,6 @@ tests/projects/CompilerCompat/local-nuget-packages/ tests/projects/CompilerCompat/lib-output-*/ tests/projects/CompilerCompat/**/bin/ tests/projects/CompilerCompat/**/obj/ + +# Complexity documentation working folder (not to be committed) +complexity/ diff --git a/src/FSharp.Core/set.fsi b/src/FSharp.Core/set.fsi index c543506c75b..abcfed1de10 100644 --- a/src/FSharp.Core/set.fsi +++ b/src/FSharp.Core/set.fsi @@ -32,6 +32,8 @@ type Set<[] 'T when 'T: comparison> = /// printfn $"The set is {numbersInSet}" /// /// + /// + /// This is an O(n log n) operation, where n is the number of elements in the sequence. /// Creates a new Set containing the elements of the given sequence. set [1; 2; 3] new: elements: seq<'T> -> Set<'T> @@ -50,6 +52,8 @@ type Set<[] 'T when 'T: comparison> = /// /// The sample evaluates to the following output: The new set is: set [1; 2] /// + /// + /// This is an O(log n) operation, where n is the number of elements in the set. member Add: value: 'T -> Set<'T> /// A useful shortcut for Set.remove. Note this operation produces a new set @@ -67,6 +71,8 @@ type Set<[] 'T when 'T: comparison> = /// /// The sample evaluates to the following output: The new set is: set [2] /// + /// + /// This is an O(log n) operation, where n is the number of elements in the set. member Remove: value: 'T -> Set<'T> /// The number of elements in the set @@ -78,6 +84,8 @@ type Set<[] 'T when 'T: comparison> = /// /// The sample evaluates to the following output: The set has 3 elements /// + /// + /// This is an O(1) operation. member Count: int /// A useful shortcut for Set.contains. See the Set module for further operations on sets. @@ -93,6 +101,8 @@ type Set<[] 'T when 'T: comparison> = /// /// The sample evaluates to the following output: Does the set contain 1? false /// + /// + /// This is an O(log n) operation, where n is the number of elements in the set. member Contains: value: 'T -> bool /// A useful shortcut for Set.isEmpty. See the Set module for further operations on sets. @@ -104,6 +114,8 @@ type Set<[] 'T when 'T: comparison> = /// /// The sample evaluates to the following output: Is the set empty? false /// + /// + /// This is an O(1) operation. member IsEmpty: bool /// Returns a new set with the elements of the second set removed from the first. @@ -121,6 +133,8 @@ type Set<[] 'T when 'T: comparison> = /// /// The sample evaluates to the following output: The new set is: set [1] /// + /// + /// This is an O(m log n) operation, where m is the number of elements in the second set and n is the number of elements in the first set. static member (-): set1: Set<'T> * set2: Set<'T> -> Set<'T> /// Compute the union of the two sets. @@ -138,6 +152,8 @@ type Set<[] 'T when 'T: comparison> = /// /// The sample evaluates to the following output: The new set is: set [1; 2; 3; 4] /// + /// + /// This is an O(m log n) operation, where m is the number of elements in the second set and n is the number of elements in the first set. static member (+): set1: Set<'T> * set2: Set<'T> -> Set<'T> /// Evaluates to "true" if all elements of the first set are in the second. @@ -154,6 +170,8 @@ type Set<[] 'T when 'T: comparison> = /// /// The sample evaluates to the following output: Is set [1; 2; 3] a subset of set [1; 2; 3; 4]? true /// + /// + /// This is an O(n log m) operation, where n is the number of elements in this set and m is the number of elements in otherSet. member IsSubsetOf: otherSet: Set<'T> -> bool /// Evaluates to "true" if all elements of the first set are in the second, and at least @@ -171,6 +189,8 @@ type Set<[] 'T when 'T: comparison> = /// /// The sample evaluates to the following output: Is set [1; 2; 3] a proper subset of set [1; 2; 3; 4]? true /// + /// + /// This is an O(n log m) operation, where n is the number of elements in this set and m is the number of elements in otherSet. member IsProperSubsetOf: otherSet: Set<'T> -> bool /// Evaluates to "true" if all elements of the second set are in the first. @@ -187,6 +207,8 @@ type Set<[] 'T when 'T: comparison> = /// /// The sample evaluates to the following output: Is set [1; 2; 3] a superset of set [1; 2; 3; 4]? false /// + /// + /// This is an O(m log n) operation, where m is the number of elements in otherSet and n is the number of elements in this set. member IsSupersetOf: otherSet: Set<'T> -> bool /// Evaluates to "true" if all elements of the second set are in the first, and at least @@ -204,6 +226,8 @@ type Set<[] 'T when 'T: comparison> = /// /// The sample evaluates to the following output: Is set [1; 2; 3] a proper superset of set [1; 2; 3; 4]? false /// + /// + /// This is an O(m log n) operation, where m is the number of elements in otherSet and n is the number of elements in this set. member IsProperSupersetOf: otherSet: Set<'T> -> bool /// Returns the lowest element in the set according to the ordering being used for the set. @@ -215,6 +239,8 @@ type Set<[] 'T when 'T: comparison> = /// /// The sample evaluates to the following output: MinimumElement: 1 /// + /// + /// This is an O(log n) operation, where n is the number of elements in the set. member MinimumElement: 'T /// Returns the highest element in the set according to the ordering being used for the set. @@ -226,6 +252,8 @@ type Set<[] 'T when 'T: comparison> = /// /// The sample evaluates to the following output: MaximumElement: 3 /// + /// + /// This is an O(log n) operation, where n is the number of elements in the set. member MaximumElement: 'T interface ICollection<'T> @@ -246,6 +274,8 @@ and [The items to store in the set. /// /// A set containing the specified items. + /// + /// This is an O(n log n) operation, where n is the number of items in the span. [] static member Create: [] items: ReadOnlySpan<'T> -> Set<'T> #endif @@ -268,6 +298,8 @@ module Set = /// /// Evaluates to set [ ]. /// + /// + /// This is an O(1) operation. [] [] val empty<'T> : Set<'T> when 'T: comparison @@ -284,6 +316,8 @@ module Set = /// /// Evaluates to set [ 7 ]. /// + /// + /// This is an O(1) operation. [] val singleton: value: 'T -> Set<'T> @@ -302,6 +336,8 @@ module Set = /// /// The sample evaluates to the following output: The new set is: set [1; 2] /// + /// + /// This is an O(log n) operation, where n is the number of elements in the set. [] val add: value: 'T -> set: Set<'T> -> Set<'T> @@ -319,6 +355,8 @@ module Set = /// /// The sample evaluates to the following output: Does the set contain 1? false /// + /// + /// This is an O(log n) operation, where n is the number of elements in the set. [] val contains: element: 'T -> set: Set<'T> -> bool @@ -337,6 +375,8 @@ module Set = /// /// The sample evaluates to the following output: Is set [1; 2; 3] a subset of set [1; 2; 3; 4]? true /// + /// + /// This is an O(m log n) operation, where m is the number of elements in set1 and n is the number of elements in set2. [] val isSubset: set1: Set<'T> -> set2: Set<'T> -> bool @@ -356,6 +396,8 @@ module Set = /// /// The sample evaluates to the following output: Is set [1; 2; 3] a proper subset of set [1; 2; 3; 4]? true /// + /// + /// This is an O(m log n) operation, where m is the number of elements in set1 and n is the number of elements in set2. [] val isProperSubset: set1: Set<'T> -> set2: Set<'T> -> bool @@ -374,6 +416,8 @@ module Set = /// /// The sample evaluates to the following output: Is set [1; 2; 3] a superset of set [1; 2; 3; 4]? false /// + /// + /// This is an O(m log n) operation, where m is the number of elements in set2 and n is the number of elements in set1. [] val isSuperset: set1: Set<'T> -> set2: Set<'T> -> bool @@ -393,6 +437,8 @@ module Set = /// /// The sample evaluates to the following output: Is set [1; 2; 3] a proper superset of set [1; 2; 3; 4]? false /// + /// + /// This is an O(m log n) operation, where m is the number of elements in set2 and n is the number of elements in set1. [] val isProperSuperset: set1: Set<'T> -> set2: Set<'T> -> bool @@ -409,6 +455,8 @@ module Set = /// /// The sample evaluates to the following output: The set has 3 elements /// + /// + /// This is an O(1) operation. [] val count: set: Set<'T> -> int @@ -428,6 +476,8 @@ module Set = /// /// The sample evaluates to the following output: Does the set contain 1? true /// + /// + /// This is an O(n) operation, where n is the number of elements in the set. [] val exists: predicate: ('T -> bool) -> set: Set<'T> -> bool @@ -446,6 +496,8 @@ module Set = /// /// The sample evaluates to the following output: The set with even numbers is set [2; 4] /// + /// + /// This is an O(n log n) operation, where n is the number of elements in the set. [] val filter: predicate: ('T -> bool) -> set: Set<'T> -> Set<'T> @@ -464,6 +516,8 @@ module Set = /// /// The sample evaluates to the following output: The set with doubled values is set [2; 4; 6] /// + /// + /// This is an O(n log n) operation, where n is the number of elements in the set. [] val map: mapping: ('T -> 'U) -> set: Set<'T> -> Set<'U> @@ -486,6 +540,8 @@ module Set = /// The product of the set is 6 /// The reverse of the set is [3; 2; 1] /// + /// + /// This is an O(n) operation, where n is the number of elements in the set. [] val fold<'T, 'State> : folder: ('State -> 'T -> 'State) -> state: 'State -> set: Set<'T> -> 'State when 'T: comparison @@ -507,6 +563,8 @@ module Set = /// The sample evaluates to the following output: The sum of the set is 6 /// The set is [1; 2; 3] /// + /// + /// This is an O(n) operation, where n is the number of elements in the set. [] val foldBack<'T, 'State> : folder: ('T -> 'State -> 'State) -> set: Set<'T> -> state: 'State -> 'State when 'T: comparison @@ -527,6 +585,8 @@ module Set = /// /// The sample evaluates to the following output: Does the set contain even numbers? false /// + /// + /// This is an O(n) operation, where n is the number of elements in the set. [] val forall: predicate: ('T -> bool) -> set: Set<'T> -> bool @@ -545,6 +605,8 @@ module Set = /// /// The sample evaluates to the following output: The intersection of set [1; 2; 3] and set [2; 3; 4] is set [2; 3] /// + /// + /// This is an O(m log n) operation, where m is the number of elements in the first set and n is the number of elements in the second set. [] val intersect: set1: Set<'T> -> set2: Set<'T> -> Set<'T> @@ -570,6 +632,8 @@ module Set = /// [["id"; "name"; "date"; "color"]; ["id"; "age"; "date"]; /// ["id"; "sex"; "date"; "animal"]] is set ["date"; "id"] /// + /// + /// This is an O((k-1) * m log n) operation, where k is the number of sets in the sequence, m is the size of each set, and n is the size of the accumulated intersection. [] val intersectMany: sets: seq> -> Set<'T> @@ -588,6 +652,8 @@ module Set = /// /// The sample evaluates to the following output: The union of set [1; 2; 3] and set [2; 3; 4] is set [1; 2; 3; 4] /// + /// + /// This is an O(m log n) operation, where m is the number of elements in the first set and n is the number of elements in the second set. [] val union: set1: Set<'T> -> set2: Set<'T> -> Set<'T> @@ -613,6 +679,8 @@ module Set = /// [["id"; "name"; "date"; "color"]; ["id"; "age"; "date"]; /// ["id"; "sex"; "date"; "animal"]] is set ["age"; "animal"; "color"; "date"; "id"; "name"; "sex"] /// + /// + /// This is an O(k * m log n) operation, where k is the number of sets in the sequence, m is the average size of each set, and n is the size of the accumulated union. [] val unionMany: sets: seq> -> Set<'T> @@ -629,6 +697,8 @@ module Set = /// /// The sample evaluates to the following output: Is the set empty? false /// + /// + /// This is an O(1) operation. [] val isEmpty: set: Set<'T> -> bool @@ -648,6 +718,8 @@ module Set = /// The set contains 2 /// The set contains 3 /// + /// + /// This is an O(n) operation, where n is the number of elements in the set. [] val iter: action: ('T -> unit) -> set: Set<'T> -> unit @@ -667,6 +739,8 @@ module Set = /// /// The sample evaluates to the following output: The partitioned sets are: (set [2; 4], set [1; 3]) /// + /// + /// This is an O(n log n) operation, where n is the number of elements in the set. [] val partition: predicate: ('T -> bool) -> set: Set<'T> -> (Set<'T> * Set<'T>) @@ -685,6 +759,8 @@ module Set = /// /// The sample evaluates to the following output: The set without 1 is set [2; 3] /// + /// + /// This is an O(log n) operation, where n is the number of elements in the set. [] val remove: value: 'T -> set: Set<'T> -> Set<'T> @@ -701,6 +777,8 @@ module Set = /// /// The sample evaluates to the following output: The min element of set [1; 2; 3] is 1 /// + /// + /// This is an O(log n) operation, where n is the number of elements in the set. [] val minElement: set: Set<'T> -> 'T @@ -717,6 +795,8 @@ module Set = /// /// The sample evaluates to the following output: The max element of set [1; 2; 3] is 3 /// + /// + /// This is an O(log n) operation, where n is the number of elements in the set. [] val maxElement: set: Set<'T> -> 'T @@ -733,6 +813,8 @@ module Set = /// /// The sample evaluates to the following output: The set is set [(1, 2, 3)] and type is "FSharpSet`1" /// + /// + /// This is an O(n log n) operation, where n is the number of elements in the list. [] val ofList: elements: 'T list -> Set<'T> @@ -750,6 +832,8 @@ module Set = /// /// The sample evaluates to the following output: The set is [1; 2; 3] and type is "FSharpList`1" /// + /// + /// This is an O(n) operation, where n is the number of elements in the set. [] val toList: set: Set<'T> -> 'T list @@ -766,6 +850,8 @@ module Set = /// /// The sample evaluates to the following output: The set is set [(1, 2, 3)] and type is "FSharpSet`1" /// + /// + /// This is an O(n log n) operation, where n is the number of elements in the array. [] val ofArray: array: 'T array -> Set<'T> @@ -783,6 +869,8 @@ module Set = /// /// The sample evaluates to the following output: The set is [|1; 2; 3|] and type is System.Int32 array /// + /// + /// This is an O(n) operation, where n is the number of elements in the set. [] val toArray: set: Set<'T> -> 'T array @@ -800,6 +888,8 @@ module Set = /// /// The sample evaluates to the following output: he set is set [1; 2; 3] and type is Microsoft.FSharp.Collections.FSharpSet`1[System.Int32] /// + /// + /// This is an O(1) operation. [] val toSeq: set: Set<'T> -> seq<'T> @@ -816,6 +906,8 @@ module Set = /// /// The sample evaluates to the following output: The set is set [(1, 2, 3)] and type is "FSharpSet`1" /// + /// + /// This is an O(n log n) operation, where n is the number of elements in the sequence. [] val ofSeq: elements: seq<'T> -> Set<'T> @@ -834,5 +926,7 @@ module Set = /// /// The sample evaluates to the following output: The difference of set [1; 2; 3] and set [2; 3; 4] is set [1] /// + /// + /// This is an O(m log n) operation, where m is the number of elements in the second set and n is the number of elements in the first set. [] val difference: set1: Set<'T> -> set2: Set<'T> -> Set<'T> From 80c54656eec3a4a869db3eaa66f8d959b54f90c4 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jan 2026 17:55:19 +0100 Subject: [PATCH 02/17] Add complexity documentation to Map module (~43 functions) Added with O(n) complexity documentation to all public Map type members and module functions in map.fsi: Type members (12): Add, Change, IsEmpty, new, ContainsKey, Count, Item, Remove, TryFind, TryGetValue, Keys, Values Module functions (31): empty, isEmpty, add, change, find, tryFind, remove, containsKey, iter, tryPick, pick, exists, filter, partition, forall, map, fold, foldBack, toSeq, toList, toArray, findKey, tryFindKey, ofList, ofSeq, ofArray, count, keys, values, minKeyValue, maxKeyValue All remarks use consistent prose style following the pattern: 'Maps are represented as binary trees so this is an O(log n) operation' Build: dotnet build src/FSharp.Core/FSharp.Core.fsproj -c Release - 0 errors Tests: XmlDocumentationValidation - 1 passed --- src/FSharp.Core/map.fsi | 86 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/FSharp.Core/map.fsi b/src/FSharp.Core/map.fsi index dba37379f64..7a9e49cc72d 100644 --- a/src/FSharp.Core/map.fsi +++ b/src/FSharp.Core/map.fsi @@ -24,6 +24,8 @@ type Map<[] 'Key, [The resulting map. /// + /// Maps are represented as binary trees so this is an O(log n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -41,6 +43,8 @@ type Map<[] 'Key, [The resulting map. /// + /// Maps are represented as binary trees so this is an O(log n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -57,6 +61,8 @@ type Map<[] 'Key, [Returns true if there are no bindings in the map. /// + /// This is an O(1) operation. + /// /// /// /// let emptyMap: Map<int, string> = Map.empty @@ -74,6 +80,8 @@ type Map<[] 'Key, [The resulting map. /// + /// This is an O(n log n) operation, where n is the number of elements in the sequence. + /// /// /// /// Map [ (1, "a"); (2, "b") ] // evaluates to map [(1, "a"); (2, "b")] @@ -87,6 +95,8 @@ type Map<[] 'Key, [True if the map contains the given key. /// + /// Maps are represented as binary trees so this is an O(log n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -99,6 +109,8 @@ type Map<[] 'Key, [The number of bindings in the map. /// + /// This is an O(n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -116,6 +128,8 @@ type Map<[] 'Key, [The value mapped to the key. /// + /// Maps are represented as binary trees so this is an O(log n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -132,6 +146,8 @@ type Map<[] 'Key, [The resulting map. /// + /// Maps are represented as binary trees so this is an O(log n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -149,6 +165,8 @@ type Map<[] 'Key, [The mapped value, or None if the key is not in the map. /// + /// Maps are represented as binary trees so this is an O(log n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -167,6 +185,8 @@ type Map<[] 'Key, [true if the value is present, false if not. /// + /// Maps are represented as binary trees so this is an O(log n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -186,6 +206,8 @@ type Map<[] 'Key, [The keys in the map. /// The sequence will be ordered by the keys of the map. /// + /// This is an O(n) operation, creating a sequence of all keys. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -198,6 +220,8 @@ type Map<[] 'Key, [All the values in the map, including the duplicates. /// The sequence will be ordered by the keys of the map. /// + /// This is an O(n) operation, creating a sequence of all values. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -230,6 +254,8 @@ module Map = /// /// The resulting map. /// + /// Maps are represented as binary trees so this is an O(log n) operation, where n is the number of bindings in the map. + /// /// /// /// let input = Map [ (1, "a"); (2, "b") ] @@ -249,6 +275,8 @@ module Map = /// /// The resulting map. /// + /// Maps are represented as binary trees so this is an O(log n) operation, where n is the number of bindings in the map. + /// /// /// /// let input = Map [ (1, "a"); (2, "b") ] @@ -269,6 +297,8 @@ module Map = /// /// The resulting map. /// + /// This is an O(n log n) operation, where n is the length of the list. + /// /// /// /// let input = [ (1, "a"); (2, "b") ] @@ -285,6 +315,8 @@ module Map = /// /// The resulting map. /// + /// This is an O(n log n) operation, where n is the length of the array. + /// /// /// /// let input = [| (1, "a"); (2, "b") |] @@ -301,6 +333,8 @@ module Map = /// /// The resulting map. /// + /// This is an O(n log n) operation, where n is the number of elements in the sequence. + /// /// /// /// let input = seq { (1, "a"); (2, "b") } @@ -318,6 +352,8 @@ module Map = /// /// The sequence of key/value pairs. /// + /// This is an O(n) operation, where n is the number of bindings in the map. + /// /// /// /// let input = Map [ (1, "a"); (2, "b") ] @@ -335,6 +371,8 @@ module Map = /// /// The list of key/value pairs. /// + /// This is an O(n) operation, where n is the number of bindings in the map. + /// /// /// /// let input = Map [ (1, "a"); (2, "b") ] @@ -352,6 +390,8 @@ module Map = /// /// The array of key/value pairs. /// + /// This is an O(n) operation, where n is the number of bindings in the map. + /// /// /// /// let input = Map [ (1, "a"); (2, "b") ] @@ -368,6 +408,8 @@ module Map = /// /// True if the map is empty. /// + /// This is an O(1) operation. + /// /// /// /// let emptyMap = Map.empty<int, string> @@ -382,6 +424,8 @@ module Map = /// The empty map. /// + /// This is an O(1) operation. + /// /// /// /// let emptyMap = Map.empty<int, string> @@ -400,6 +444,8 @@ module Map = /// /// The value mapped to the given key. /// + /// Maps are represented as binary trees so this is an O(log n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -418,6 +464,8 @@ module Map = /// /// The first result. /// + /// This is an O(n) operation in the worst case, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b"); (10, "ccc"); (20, "ddd") ] @@ -448,6 +496,8 @@ module Map = /// /// The first result. /// + /// This is an O(n) operation in the worst case, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b"); (10, "ccc"); (20, "ddd") ] @@ -475,6 +525,8 @@ module Map = /// /// The final state value. /// + /// This is an O(n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -496,6 +548,8 @@ module Map = /// /// The final state value. /// + /// This is an O(n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -514,6 +568,8 @@ module Map = /// The function to apply to each key/value pair. /// The input map. /// + /// This is an O(n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -533,6 +589,8 @@ module Map = /// /// True if the predicate returns true for one of the key/value pairs. /// + /// This is an O(n) operation in the worst case, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -551,6 +609,8 @@ module Map = /// /// The filtered map. /// + /// This is an O(n log n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -569,6 +629,8 @@ module Map = /// /// True if the predicate evaluates to true for all of the bindings in the map. /// + /// This is an O(n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -589,6 +651,8 @@ module Map = /// /// The resulting map of keys and transformed values. /// + /// This is an O(n) operation, creating a new map with the same keys. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -606,6 +670,8 @@ module Map = /// /// True if the map contains the key. /// + /// Maps are represented as binary trees so this is an O(log n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -626,6 +692,8 @@ module Map = /// A pair of maps in which the first contains the elements for which the predicate returned true /// and the second containing the elements for which the predicated returned false. /// + /// This is an O(n log n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -643,6 +711,8 @@ module Map = /// /// The resulting map. /// + /// Maps are represented as binary trees so this is an O(log n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -662,6 +732,8 @@ module Map = /// /// The found Some value or None. /// + /// Maps are represented as binary trees so this is an O(log n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -682,6 +754,8 @@ module Map = /// /// The first key for which the predicate evaluates true. /// + /// This is an O(n) operation in the worst case, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -701,6 +775,8 @@ module Map = /// /// The first key for which the predicate returns true or None if the predicate evaluates to false for each key/value pair. /// + /// This is an O(n) operation in the worst case, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -714,6 +790,8 @@ module Map = /// The number of bindings in the map. /// + /// This is an O(n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -727,6 +805,8 @@ module Map = /// The keys in the map. /// The sequence will be ordered by the keys of the map. /// + /// This is an O(n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -740,6 +820,8 @@ module Map = /// The values in the map, including the duplicates. /// The sequence will be ordered by the keys of the map. /// + /// This is an O(n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -756,6 +838,8 @@ module Map = /// The input map. /// Thrown if the map is empty. /// + /// This is an O(log n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] @@ -772,6 +856,8 @@ module Map = /// The input map. /// Thrown if the map is empty. /// + /// This is an O(log n) operation, where n is the number of bindings in the map. + /// /// /// /// let sample = Map [ (1, "a"); (2, "b") ] From 876e52d61072259495d3c91a0c652d2b1daab602 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jan 2026 18:10:43 +0100 Subject: [PATCH 03/17] Add complexity documentation for @ operator in prim-types.fsi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add O(n) complexity remarks for the @ (append) operator Sprint 1 DoD: - Build: ✅ 0 errors - XML tests: ✅ Passed - Map.fsi: ✅ 44 remarks - @ operator: ✅ Documented - No duplicates: ✅ Verified --- src/FSharp.Core/prim-types.fsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/FSharp.Core/prim-types.fsi b/src/FSharp.Core/prim-types.fsi index cbbee78773a..5e83b8957fe 100644 --- a/src/FSharp.Core/prim-types.fsi +++ b/src/FSharp.Core/prim-types.fsi @@ -3811,6 +3811,8 @@ namespace Microsoft.FSharp.Core /// l1 @ l2 // Evaluates to ['a'; 'b'; 'c'; 'd'; 'e'; 'f'] /// /// + /// + /// This is an O(n) operation, where n is the length of the first list. /// val (@): list1: 'T list -> list2: 'T list -> 'T list From 5ad4b7b5ca324109d3119204caf6e399af80d231 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jan 2026 18:30:20 +0100 Subject: [PATCH 04/17] Add complexity documentation to List module (~100 functions) - Add with O() complexity info to all public List module functions - Append complexity to existing remarks where applicable - Follow prose format: 'This is an O(n) operation...' - Lists are represented as linked lists - O(1) for head/tail, O(n) for indexing --- src/FSharp.Core/list.fsi | 210 +++++++++++++++++++++++++++++++++++---- 1 file changed, 193 insertions(+), 17 deletions(-) diff --git a/src/FSharp.Core/list.fsi b/src/FSharp.Core/list.fsi index 1b48f6d9c60..9912afdfbd2 100644 --- a/src/FSharp.Core/list.fsi +++ b/src/FSharp.Core/list.fsi @@ -34,6 +34,8 @@ module List = /// [ (1, "Kirk"); (1, "Spock"); (1, "McCoy"); (2, "Kirk"); (2, "Spock"); (2, "McCoy") ] /// /// + /// + /// This is an O(n*m) operation, where n and m are the lengths of the input lists. [] val allPairs: list1:'T1 list -> list2:'T2 list -> ('T1 * 'T2) list @@ -56,6 +58,8 @@ module List = /// [ 1; 2; 3; 4; 5; 6; 7 ] /// /// + /// + /// This is an O(n) operation, where n is the length of the first list. [] val append: list1: 'T list -> list2: 'T list -> 'T list @@ -77,6 +81,8 @@ module List = /// /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val inline average : list:^T list -> ^T when ^T : (static member (+) : ^T * ^T -> ^T) @@ -110,6 +116,8 @@ module List = /// 51.0 /// /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val inline averageBy: projection:('T -> ^U) -> list:'T list -> ^U when ^U : (static member (+) : ^U * ^U -> ^U) @@ -202,6 +210,8 @@ module List = /// /// /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val choose: chooser:('T -> 'U option) -> list:'T list -> 'U list @@ -239,6 +249,8 @@ module List = /// [ [ 1; 2; 3; 4; 5 ] ] /// /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val chunkBySize: chunkSize:int -> list:'T list -> 'T list list @@ -255,6 +267,8 @@ module List = /// /// The sample evaluates to [1; 1; 2; 1; 2; 3; 1; 2; 3; 4] (added extra spaces for easy reading) /// + /// + /// This is an O(n) operation, where n is the total length of all resulting sublists. [] val collect: mapping:('T -> 'U list) -> list:'T list -> 'U list @@ -335,6 +349,8 @@ module List = /// /// Evaluates to -1 /// + /// + /// This is an O(min(n,m)) operation, where n and m are the lengths of the lists. [] val inline compareWith: comparer:('T -> 'T -> int) -> list1:'T list -> list2:'T list -> int @@ -352,6 +368,8 @@ module List = /// input |> List.concat // evaluates [1; 2; 3; 4; 5; 6; 7; 8; 9] /// /// + /// + /// This is an O(n) operation, where n is the total number of elements across all lists. [] val concat: lists:seq<'T list> -> 'T list @@ -393,6 +411,8 @@ module List = /// /// Evaluates to false. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val inline contains: value:'T -> source:'T list -> bool when 'T : equality @@ -412,6 +432,8 @@ module List = /// /// Evaluates to [6; 1; 2; 3; 4; 5]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val distinct: list:'T list -> 'T list when 'T : equality @@ -433,6 +455,8 @@ module List = /// input |> List.distinctBy isEven // evaluates [6; 1] /// /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val distinctBy: projection:('T -> 'Key) -> list:'T list -> 'T list when 'Key : equality @@ -453,6 +477,8 @@ module List = /// /// Evaluates [('H', 1); ('a', 1); ('p', 2); ('y', 1)] /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val countBy : projection:('T -> 'Key) -> list:'T list -> ('Key * int) list when 'Key : equality @@ -478,10 +504,14 @@ module List = /// /// Evaluates to [[1; 2; 3]; [4; 5; 6]; [7; 8]; [9; 10]]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val splitInto: count:int -> list:'T list -> 'T list list /// Returns an empty list of the given type. + /// + /// This is an O(1) operation. [] [] val empty<'T> : 'T list @@ -517,6 +547,8 @@ module List = /// [1..5] |> List.except [0..10] // evaluates [] /// /// + /// + /// This is an O(n+m) operation, where n is the length of the list and m is the length of the items to exclude. [] val except: itemsToExclude:seq<'T> -> list:'T list -> 'T list when 'T : equality @@ -549,6 +581,8 @@ module List = /// /// Will throw the exception: System.ArgumentException: The input sequence contains more than one element /// + /// + /// This is an O(1) operation. [] val exactlyOne: list:'T list -> 'T @@ -565,6 +599,8 @@ module List = /// ([] : int list) |> List.tryExactlyOne // evaluates None /// /// + /// + /// This is an O(1) operation. [] val tryExactlyOne: list:'T list -> 'T option @@ -572,7 +608,7 @@ module List = /// /// The predicate is applied to the elements of the input list. If any application /// returns true then the overall result is true and no further elements are tested. - /// Otherwise, false is returned. + /// Otherwise, false is returned. This is an O(n) operation in the worst case, where n is the length of the list. /// The function to test the input elements. /// The input list. /// @@ -596,7 +632,7 @@ module List = /// two lengths of the collections. If any application returns true then the overall result is /// true and no further elements are tested. Otherwise, if one collections is longer /// than the other then the exception is raised. - /// Otherwise, false is returned. + /// Otherwise, false is returned. This is an O(n) operation in the worst case, where n is the length of the lists. /// /// The function to test the input elements. /// The first input list. @@ -643,6 +679,8 @@ module List = /// input |> List.find (fun (x,_) -> x |> isGreaterThan 6) // raises an exception /// /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the list. [] val find: predicate:('T -> bool) -> list:'T list -> 'T @@ -669,6 +707,8 @@ module List = /// input |> List.findBack (fun (x,_) -> x |> isGreaterThan 6) // raises an exception /// /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val findBack: predicate:('T -> bool) -> list:'T list -> 'T @@ -696,6 +736,8 @@ module List = /// input |> List.findIndex (fun (x,_) -> x |> isGreaterThan 6) // raises an exception /// /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the list. [] val findIndex: predicate:('T -> bool) -> list:'T list -> int @@ -723,6 +765,8 @@ module List = /// input |> List.findIndexBack (fun (x,_) -> x |> isGreaterThan 6) // raises an exception /// /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val findIndexBack: predicate:('T -> bool) -> list:'T list -> int @@ -746,6 +790,8 @@ module List = /// /// Evaluates to [(2, "Kirk"); (4, "Spock")] /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val filter: predicate:('T -> bool) -> list:'T list -> 'T list @@ -792,6 +838,8 @@ module List = /// { fruit = Apple; quantity = 1 }] /// /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> list:'T list -> 'State @@ -822,6 +870,8 @@ module List = /// /// Evaluates to 2. Note acc is a commonly used abbreviation for "accumulator". /// + /// + /// This is an O(n) operation, where n is the length of the lists. [] val fold2<'T1,'T2,'State> : folder:('State -> 'T1 -> 'T2 -> 'State) -> state:'State -> list1:'T1 list -> list2:'T2 list -> 'State @@ -866,6 +916,8 @@ module List = /// { fruit = Orange; quantity = 1 }] /// /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val foldBack<'T,'State> : folder:('T -> 'State -> 'State) -> list:'T list -> state:'State -> 'State @@ -912,6 +964,8 @@ module List = /// /// Note acc is a commonly used abbreviation for "accumulator". /// + /// + /// This is an O(n) operation, where n is the length of the lists. [] val foldBack2<'T1,'T2,'State> : folder:('T1 -> 'T2 -> 'State -> 'State) -> list1:'T1 list -> list2:'T2 list -> state:'State -> 'State @@ -919,7 +973,7 @@ module List = /// /// The predicate is applied to the elements of the input list. If any application /// returns false then the overall result is false and no further elements are tested. - /// Otherwise, true is returned. + /// Otherwise, true is returned. This is an O(n) operation in the worst case, where n is the length of the list. /// The function to test the input elements. /// The input list. /// @@ -943,7 +997,7 @@ module List = /// two lengths of the collections. If any application returns false then the overall result is /// false and no further elements are tested. Otherwise, if one collection is longer /// than the other then the exception is raised. - /// Otherwise, true is returned. + /// Otherwise, true is returned. This is an O(n) operation in the worst case, where n is the length of the lists. /// The function to test the input elements. /// The first input list. /// The second input list. @@ -1001,6 +1055,8 @@ module List = /// /// Evaluates to [(1, [1; 3; 5]); (0, [2; 4])] /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val groupBy: projection:('T -> 'Key) -> list:'T list -> ('Key * 'T list) list when 'Key : equality @@ -1027,6 +1083,8 @@ module List = /// /// Throws ArgumentException /// + /// + /// Lists are represented as linked lists so this is an O(1) operation. [] val head: list:'T list -> 'T @@ -1045,6 +1103,8 @@ module List = /// /// Evaluates to [(0, "a"); (1, "b"); (2, "c")] /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val indexed: list:'T list -> (int * 'T) list @@ -1070,6 +1130,8 @@ module List = /// /// Throws ArgumentException /// + /// + /// This is an O(n) operation, where n is the specified count. [] val init: length:int -> initializer:(int -> 'T) -> 'T list @@ -1092,6 +1154,8 @@ module List = /// /// Evaluates to false /// + /// + /// This is an O(1) operation. [] val isEmpty: list:'T list -> bool @@ -1121,6 +1185,8 @@ module List = /// /// Throws ArgumentException /// + /// + /// Lists are represented as linked lists so this is an O(n) operation, where n is the index. [] val item: index:int -> list:'T list -> 'T @@ -1143,6 +1209,8 @@ module List = /// /// in the console. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val inline iter: action:('T -> unit) -> list:'T list -> unit @@ -1168,6 +1236,8 @@ module List = /// /// in the console. /// + /// + /// This is an O(n) operation, where n is the length of the lists. [] val iter2: action:('T1 -> 'T2 -> unit) -> list1:'T1 list -> list2:'T2 list -> unit @@ -1191,6 +1261,8 @@ module List = /// /// in the console. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val inline iteri: action:(int -> 'T -> unit) -> list:'T list -> unit @@ -1217,6 +1289,8 @@ module List = /// /// in the console. /// + /// + /// This is an O(n) operation, where n is the length of the lists. [] val iteri2: action:(int -> 'T1 -> 'T2 -> unit) -> list1:'T1 list -> list2:'T2 list -> unit @@ -1241,6 +1315,8 @@ module List = /// /// Throws ArgumentException /// + /// + /// Lists are represented as linked lists so this is an O(n) operation, where n is the length of the list. [] val last: list:'T list -> 'T @@ -1250,7 +1326,7 @@ module List = /// /// The length of the list. /// - /// The notation array.Length is preferred. + /// The notation array.Length is preferred. This is an O(n) operation, where n is the length of the list. /// /// /// @@ -1283,6 +1359,8 @@ module List = /// /// Evaluates to None /// + /// + /// Lists are represented as linked lists so this is an O(n) operation, where n is the length of the list. [] val tryLast: list:'T list -> 'T option @@ -1302,6 +1380,8 @@ module List = /// /// Evaluates to [ 1; 3; 2 ] /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val map: mapping:('T -> 'U) -> list:'T list -> 'U list @@ -1323,6 +1403,8 @@ module List = /// /// Evaluates to seq ['a'; 'd'; 'o'] /// + /// + /// This is an O(n) operation, where n is the length of the lists. [] val map2: mapping:('T1 -> 'T2 -> 'U) -> list1:'T1 list -> list2:'T2 list -> 'U list @@ -1347,6 +1429,8 @@ module List = /// Evaluates to [ "all"; "the"; "time" ] /// /// + /// + /// This is an O(n) operation, where n is the length of the lists. [] val map3: mapping:('T1 -> 'T2 -> 'T3 -> 'U) -> list1:'T1 list -> list2:'T2 list -> list3:'T3 list -> 'U list @@ -1376,6 +1460,8 @@ module List = /// Evaluates newCharges to [In 2; Out 4; In 6] and balance to 2. /// Note acc is a commonly used abbreviation for "accumulator". /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val mapFold<'T,'State,'Result> : mapping:('State -> 'T -> 'Result * 'State) -> state:'State -> list:'T list -> 'Result list * 'State @@ -1405,6 +1491,8 @@ module List = /// Evaluates newCharges to [In 2; Out 4; In 6] and balance to 2. /// Note acc is a commonly used abbreviation for "accumulator". /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val mapFoldBack<'T,'State,'Result> : mapping:('T -> 'State -> 'Result * 'State) -> list:'T list -> state:'State -> 'Result list * 'State @@ -1425,6 +1513,8 @@ module List = /// /// Evaluates to [ 10; 11; 12 ] /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val mapi: mapping:(int -> 'T -> 'U) -> list:'T list -> 'U list @@ -1445,12 +1535,14 @@ module List = /// /// Evaluates to [(0, 'a'); (1, 'd'); (2, 'o')] /// + /// + /// This is an O(n) operation, where n is the length of the lists. [] val mapi2: mapping:(int -> 'T1 -> 'T2 -> 'U) -> list1:'T1 list -> list2:'T2 list -> 'U list /// Return the greatest of all elements of the list, compared via Operators.max. /// - /// Raises if list is empty + /// Raises if list is empty This is an O(n) operation, where n is the length of the list. /// The input list. /// /// Thrown when the list is empty. @@ -1479,7 +1571,7 @@ module List = /// Returns the greatest of all elements of the list, compared via Operators.max on the function result. /// - /// Raises if list is empty. + /// Raises if list is empty. This is an O(n) operation, where n is the length of the list. /// The function to transform the list elements into the type to be compared. /// The input list. /// @@ -1509,7 +1601,7 @@ module List = /// Returns the lowest of all elements of the list, compared via Operators.min. /// - /// Raises if list is empty + /// Raises if list is empty This is an O(n) operation, where n is the length of the list. /// The input list. /// /// Thrown when the list is empty. @@ -1538,7 +1630,7 @@ module List = /// Returns the lowest of all elements of the list, compared via Operators.min on the function result /// - /// Raises if list is empty. + /// Raises if list is empty. This is an O(n) operation, where n is the length of the list. /// The function to transform list elements into the type to be compared. /// The input list. /// @@ -1574,6 +1666,8 @@ module List = /// The value at the given index. /// /// Thrown when the index is negative or the input list does not contain enough elements. + /// + /// Lists are represented as linked lists so this is an O(n) operation, where n is the index. [] [] val nth: list:'T list -> index:int -> 'T @@ -1592,6 +1686,8 @@ module List = /// /// Evaluates to [ 1; 2; 5 ]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val ofArray : array:'T array -> 'T list @@ -1609,6 +1705,8 @@ module List = /// /// Evaluates to [ 1; 2; 5 ]. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val ofSeq: source:seq<'T> -> 'T list @@ -1628,6 +1726,8 @@ module List = /// /// Evaluates to [(1, 2); (2, 3); (3, 4)]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val pairwise: list:'T list -> ('T * 'T) list @@ -1649,6 +1749,8 @@ module List = /// /// Evaluates evens to [2; 4] and odds to [1; 3]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val partition: predicate:('T -> bool) -> list:'T list -> ('T list * 'T list) @@ -1681,6 +1783,8 @@ module List = /// Throws KeyNotFoundException. /// /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the list. [] val pick: chooser:('T -> 'U option) -> list:'T list -> 'U @@ -1702,6 +1806,8 @@ module List = /// /// Evaluates to [4; 1; 2; 3]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val permute: indexMap:(int -> int) -> list:'T list -> 'T list @@ -1711,7 +1817,7 @@ module List = /// Return the final result. If the input function is f and the elements are i0...iN then computes /// f (... (f i0 i1) i2 ...) iN. /// - /// Raises if list is empty + /// Raises if list is empty This is an O(n) operation, where n is the length of the list. /// /// The function to reduce two list elements to a single element. /// The input list. @@ -1751,6 +1857,8 @@ module List = /// /// Evaluates to 2431, by computing 1 + (3 + (4 + 2 * 10) * 10) * 10 /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val reduceBack: reduction:('T -> 'T -> 'T) -> list:'T list -> 'T @@ -1767,6 +1875,8 @@ module List = /// /// Evaluates to [ "a"; "a"; "a" ]. /// + /// + /// This is an O(n) operation, where n is the specified count. [] val replicate: count:int -> initial:'T -> 'T list @@ -1784,6 +1894,8 @@ module List = /// /// Evaluates to [ 2; 1; 0 ]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val rev: list:'T list -> 'T list @@ -1815,6 +1927,8 @@ module List = /// state, 1 the next state, -1 the next state, and 2 the final state. /// Note acc is a commonly used abbreviation for "accumulator". /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val scan<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> list:'T list -> 'State list @@ -1844,6 +1958,8 @@ module List = /// are produced from back to front. /// Note acc is a commonly used abbreviation for "accumulator". /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val scanBack<'T,'State> : folder:('T -> 'State -> 'State) -> list:'T list -> state:'State -> 'State list @@ -1859,6 +1975,8 @@ module List = /// /// Evaluates to [ 7 ]. /// + /// + /// This is an O(1) operation. [] val inline singleton: value:'T -> 'T list @@ -1898,6 +2016,8 @@ module List = /// /// Evaluates to ["a"; "b"; "c"; "d"]. /// + /// + /// This is an O(n) operation, where n is the number of elements to skip. [] val skip: count:int -> list: 'T list -> 'T list @@ -1918,12 +2038,14 @@ module List = /// Evaluates to ["bbb"; "cc"; "d"] /// /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the list. [] val skipWhile: predicate:('T -> bool) -> list:'T list -> 'T list /// Sorts the given list using the given comparison function. /// - /// This is a stable sort, i.e. the original order of equal elements is preserved. + /// This is a stable sort, i.e. the original order of equal elements is preserved. This is an O(n log n) operation, where n is the length of the list. /// The function to compare the list elements. /// The input list. /// @@ -1947,7 +2069,7 @@ module List = /// Sorts the given list using keys given by the given projection. Keys are compared using . /// - /// This is a stable sort, i.e. the original order of equal elements is preserved. + /// This is a stable sort, i.e. the original order of equal elements is preserved. This is an O(n log n) operation, where n is the length of the list. /// The function to transform the list elements into the type to be compared. /// The input list. /// @@ -1966,7 +2088,7 @@ module List = /// Sorts the given list using . /// - /// This is a stable sort, i.e. the original order of equal elements is preserved. + /// This is a stable sort, i.e. the original order of equal elements is preserved. This is an O(n log n) operation, where n is the length of the list. /// The input list. /// /// The sorted list. @@ -2000,12 +2122,14 @@ module List = /// /// Evaluates front to [8; 4; 3] and back to [1; 6; 1]. /// + /// + /// This is an O(n) operation, where n is the index. [] val splitAt: index:int -> list:'T list -> ('T list * 'T list) /// Sorts the given list in descending order using keys given by the given projection. Keys are compared using . /// - /// This is a stable sort, i.e. the original order of equal elements is preserved. + /// This is a stable sort, i.e. the original order of equal elements is preserved. This is an O(n log n) operation, where n is the length of the list. /// The function to transform the list elements into the type to be compared. /// The input list. /// @@ -2024,7 +2148,7 @@ module List = /// Sorts the given list in descending order using . /// - /// This is a stable sort, i.e. the original order of equal elements is preserved. + /// This is a stable sort, i.e. the original order of equal elements is preserved. This is an O(n log n) operation, where n is the length of the list. /// The input list. /// /// The sorted list. @@ -2054,6 +2178,8 @@ module List = /// /// Evaluates to 11. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val inline sum: list:^T list -> ^T when ^T : (static member (+) : ^T * ^T -> ^T) @@ -2074,6 +2200,8 @@ module List = /// /// Evaluates to 7. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val inline sumBy: projection:('T -> ^U) -> list:'T list -> ^U when ^U : (static member (+) : ^U * ^U -> ^U) @@ -2096,13 +2224,15 @@ module List = /// Evaluates to ["bb"; "ccc"] /// /// + /// + /// Lists are represented as linked lists so this is an O(1) operation. [] val tail: list:'T list -> 'T list /// Returns the first N elements of the list. /// Throws InvalidOperationException /// if the count exceeds the number of elements in the list. List.truncate - /// returns as many items as the list contains instead of throwing an exception. + /// returns as many items as the list contains instead of throwing an exception. This is an O(n) operation, where n is the number of elements to take. /// /// The number of items to take. /// The input list. @@ -2158,6 +2288,8 @@ module List = /// /// Evaluates to ["a"; "bb"] /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the list. [] val takeWhile: predicate:('T -> bool) -> list:'T list -> 'T list @@ -2175,6 +2307,8 @@ module List = /// /// Evaluates to [| 1; 2; 5 |]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val toArray: list:'T list -> 'T array @@ -2192,6 +2326,8 @@ module List = /// /// Evaluates to seq { 1; 2; 5 }. /// + /// + /// This is an O(1) operation. [] val toSeq: list:'T list -> seq<'T> @@ -2219,6 +2355,8 @@ module List = /// /// Evaluates to None /// + /// + /// Lists are represented as linked lists so this is an O(1) operation. [] val tryHead: list:'T list -> 'T option @@ -2241,6 +2379,8 @@ module List = /// /// Evaluates to [ [10; 11]; [20; 21]; [30; 31] ]. /// + /// + /// This is an O(n*m) operation, where n is the number of inner lists and m is the length of each inner list. [] val transpose: lists:seq<'T list> -> 'T list list @@ -2277,6 +2417,8 @@ module List = /// /// Evaluates to the empty list. /// + /// + /// This is an O(n) operation, where n is the number of elements to return. [] val truncate: count:int -> list:'T list -> 'T list @@ -2307,6 +2449,8 @@ module List = /// Evaluates to None. /// /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the list. [] val tryPick: chooser:('T -> 'U option) -> list:'T list -> 'U option @@ -2336,6 +2480,8 @@ module List = /// /// Evaluates to None /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the list. [] val tryFind: predicate:('T -> bool) -> list:'T list -> 'T option @@ -2365,6 +2511,8 @@ module List = /// /// Evaluates to None /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val tryFindBack: predicate:('T -> bool) -> list:'T list -> 'T option @@ -2395,6 +2543,8 @@ module List = /// /// Evaluates to None /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the list. [] val tryFindIndex: predicate:('T -> bool) -> list:'T list -> int option @@ -2423,6 +2573,8 @@ module List = /// /// Evaluates to None. /// + /// + /// Lists are represented as linked lists so this is an O(n) operation, where n is the index. [] val tryItem: index:int -> list:'T list -> 'T option @@ -2453,6 +2605,8 @@ module List = /// /// Evaluates to None /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val tryFindIndexBack: predicate:('T -> bool) -> list:'T list -> int option @@ -2472,6 +2626,8 @@ module List = /// /// Evaluates to [1; 2; 4; 8; 16; 32; 64] /// + /// + /// This is an O(n) operation, where n is the number of elements generated. [] val unfold<'T,'State> : generator:('State -> ('T * 'State) option) -> state:'State -> 'T list @@ -2489,6 +2645,8 @@ module List = /// /// Evaluates numbers to [1; 2] and names to ["one"; "two"]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val unzip: list:('T1 * 'T2) list -> ('T1 list * 'T2 list) @@ -2506,6 +2664,8 @@ module List = /// /// Evaluates numbers to [1; 2], names to ["one"; "two"] and roman to ["I"; "II"]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val unzip3: list:('T1 * 'T2 * 'T3) list -> ('T1 list * 'T2 list * 'T3 list) @@ -2517,7 +2677,7 @@ module List = /// /// A list containing only the elements that satisfy the predicate. /// - /// This is identical to List.filter. + /// This is identical to List.filter. This is an O(n) operation, where n is the length of the list. /// /// Select only the even numbers: /// @@ -2548,6 +2708,8 @@ module List = /// /// Evaluates to [[1; 2; 3]; [2; 3; 4]; [3; 4; 5]] /// + /// + /// This is an O(n*windowSize) operation, where n is the length of the list. [] val windowed: windowSize:int -> list:'T list -> 'T list list @@ -2567,6 +2729,8 @@ module List = /// /// Evaluates to [(1, "one"); (2, "two")]. /// + /// + /// This is an O(n) operation, where n is the length of the lists. [] val zip: list1:'T1 list -> list2:'T2 list -> ('T1 * 'T2) list @@ -2588,6 +2752,8 @@ module List = /// /// Evaluates to [(1, "one", "I"); (2, "two", "II")]. /// + /// + /// This is an O(n) operation, where n is the length of the lists. [] val zip3: list1:'T1 list -> list2:'T2 list -> list3:'T3 list -> ('T1 * 'T2 * 'T3) list @@ -2608,6 +2774,8 @@ module List = /// /// let inputs = [ 0; 2 ] /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val removeAt: index: int -> source: 'T list -> 'T list @@ -2629,6 +2797,8 @@ module List = /// /// Evaluates to [ 0; 3 ]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val removeManyAt: index: int -> count: int -> source: 'T list -> 'T list @@ -2650,6 +2820,8 @@ module List = /// /// Evaluates to [ 0; 9; 2 ]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val updateAt: index: int -> value: 'T -> source: 'T list -> 'T list @@ -2671,6 +2843,8 @@ module List = /// /// Evaluates to [ 0; 9; 1; 2 ]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val insertAt: index: int -> value: 'T -> source: 'T list -> 'T list @@ -2692,6 +2866,8 @@ module List = /// Evaluates to [ 0; 8; 9; 1; 2 ]. /// /// + /// + /// This is an O(n+m) operation, where n is the length of the list and m is the number of elements to insert. [] val insertManyAt: index: int -> values: seq<'T> -> source: 'T list -> 'T list From 082a81736d95438289b742027c1c5b88ee59da6c Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jan 2026 18:46:58 +0100 Subject: [PATCH 05/17] Add complexity documentation to Array and Seq modules (~224 functions) Array module: 132 complexity remarks added - O(1) for length, get, set, head, last, isEmpty, item, toSeq, singleton - O(n) for most iteration/mapping operations - O(n log n) for sorting operations - O(n*m) for allPairs, transpose - O(min(n,m)) for compareWith Seq module: 92 complexity remarks added - Lazy construction O(1) with O(n) enumeration for most operations - O(n) for immediate operations like fold, iter, length - O(n log n) for sorting - O(k) space for distinct operations where k is unique elements --- src/FSharp.Core/array.fsi | 264 ++++++++++++++++++++++++++++++++++++++ src/FSharp.Core/seq.fsi | 184 ++++++++++++++++++++++++++ 2 files changed, 448 insertions(+) diff --git a/src/FSharp.Core/array.fsi b/src/FSharp.Core/array.fsi index 65def57f048..9a517fa5063 100644 --- a/src/FSharp.Core/array.fsi +++ b/src/FSharp.Core/array.fsi @@ -33,6 +33,8 @@ module Array = /// [| (1, 3); (1, 4); (2, 3); (2, 4) |] /// /// + /// + /// This is an O(n*m) operation, where n and m are the lengths of the arrays. [] val allPairs: array1: 'T1 array -> array2: 'T2 array -> ('T1 * 'T2) array @@ -76,6 +78,8 @@ module Array = /// /// Throws ArgumentException /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline average: array: ^T array -> ^T @@ -115,6 +119,8 @@ module Array = /// /// Throws ArgumentException /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline averageBy: projection: ('T -> ^U) -> array: 'T array -> ^U @@ -152,6 +158,8 @@ module Array = /// /// After evaluation target contains [| 0; 1; 2; 13; 14; 5 |]. /// + /// + /// This is an O(count) operation. [] val inline blit: source: 'T array -> sourceIndex: int -> target: 'T array -> targetIndex: int -> count: int -> unit @@ -183,6 +191,8 @@ module Array = /// /// Evaluates to [| 1; 2; 3; 4 |] /// + /// + /// This is an O(n) operation, where n is the total output length. [] val collect: mapping: ('T -> 'U array) -> array: 'T array -> 'U array @@ -266,6 +276,8 @@ module Array = /// /// Evaluates to -1 /// + /// + /// This is an O(min(n,m)) operation, where n and m are the lengths of the arrays. [] val inline compareWith: comparer: ('T -> 'T -> int) -> array1: 'T array -> array2: 'T array -> int @@ -303,6 +315,8 @@ module Array = /// [| 1; 2 |] |> Array.contains 5 // evaluates to false /// /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline contains: value: 'T -> array: 'T array -> bool when 'T: equality @@ -346,6 +360,8 @@ module Array = /// /// Evaluates to [| ("a", 2); ("b", 1) |] /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val countBy: projection: ('T -> 'Key) -> array: 'T array -> ('Key * int) array when 'Key: equality @@ -376,6 +392,8 @@ module Array = /// After evaluation of the last line array contains[| { contents = "b"}; { contents = "b"} |]. /// Note each entry in the array is the same mutable cell object. /// + /// + /// This is an O(n) operation, where n is the count. [] val create: count: int -> value: 'T -> 'T array @@ -405,6 +423,8 @@ module Array = /// /// Evaluates to None /// + /// + /// This is an O(1) operation. [] val tryHead: array: 'T array -> 'T option @@ -437,6 +457,8 @@ module Array = /// Evaluates to None. /// /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val tryPick: chooser: ('T -> 'U option) -> array: 'T array -> 'U option @@ -458,6 +480,8 @@ module Array = /// /// After evaluation target contains [| 0; 1; 2; 100; 100; 5 |]. /// + /// + /// This is an O(count) operation. [] val fill: target: 'T array -> targetIndex: int -> count: int -> value: 'T -> unit @@ -492,6 +516,8 @@ module Array = /// Throws KeyNotFoundException. /// /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val pick: chooser: ('T -> 'U option) -> array: 'T array -> 'U @@ -523,6 +549,8 @@ module Array = /// /// Evaluates to [| 2 |] /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val choose: chooser: ('T -> 'U option) -> array: 'T array -> 'U array @@ -553,6 +581,8 @@ module Array = /// /// Throws ArgumentException /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val chunkBySize: chunkSize: int -> array: 'T array -> 'T array array @@ -574,6 +604,8 @@ module Array = /// /// Evaluates to [| 1; 2; 3 |] /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val distinct: array: 'T array -> 'T array when 'T: equality @@ -596,6 +628,8 @@ module Array = /// /// Evaluates to [| { Bar = 1 }; { Bar = 2 }; { Bar = 3 } |] /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val distinctBy: projection: ('T -> 'Key) -> array: 'T array -> 'T array when 'Key: equality @@ -626,6 +660,8 @@ module Array = /// /// Throws ArgumentException /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val splitInto: count: int -> array: 'T array -> 'T array array @@ -676,6 +712,8 @@ module Array = /// /// Throws ArgumentException /// + /// + /// This is an O(1) operation. [] val exactlyOne: array: 'T array -> 'T @@ -713,6 +751,8 @@ module Array = /// /// Evaluates to None /// + /// + /// This is an O(1) operation. [] val tryExactlyOne: array: 'T array -> 'T option @@ -736,6 +776,8 @@ module Array = /// /// Evaluates to [| 2; 4 |] /// + /// + /// This is an O(n+m) operation using hash-based exclusion. [] val except: itemsToExclude: seq<'T> -> array: 'T array -> 'T array when 'T: equality @@ -769,6 +811,8 @@ module Array = /// /// Evaluates to false /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val inline exists: predicate: ('T -> bool) -> array: 'T array -> bool @@ -808,6 +852,8 @@ module Array = /// /// Evaluates to true /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the arrays. [] val exists2: predicate: ('T1 -> 'T2 -> bool) -> array1: 'T1 array -> array2: 'T2 array -> bool @@ -829,6 +875,8 @@ module Array = /// /// Evaluates to [| 2; 4 |] /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val filter: predicate: ('T -> bool) -> array: 'T array -> 'T array @@ -861,6 +909,8 @@ module Array = /// /// Throws KeyNotFoundException /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val find: predicate: ('T -> bool) -> array: 'T array -> 'T @@ -893,6 +943,8 @@ module Array = /// /// Throws KeyNotFoundException /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val findBack: predicate: ('T -> bool) -> array: 'T array -> 'T @@ -925,6 +977,8 @@ module Array = /// /// Throws KeyNotFoundException /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val findIndex: predicate: ('T -> bool) -> array: 'T array -> int @@ -958,6 +1012,8 @@ module Array = /// /// Throws KeyNotFoundException /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val findIndexBack: predicate: ('T -> bool) -> array: 'T array -> int @@ -983,6 +1039,8 @@ module Array = /// [1; 2] |> Array.forall isEven // evaluates to false /// /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val forall: predicate: ('T -> bool) -> array: 'T array -> bool @@ -1032,6 +1090,8 @@ module Array = /// /// Throws ArgumentException. /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the arrays. [] val forall2: predicate: ('T1 -> 'T2 -> bool) -> array1: 'T1 array -> array2: 'T2 array -> bool @@ -1062,6 +1122,8 @@ module Array = /// /// Evaluates to 2 /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val fold<'T, 'State> : folder: ('State -> 'T -> 'State) -> state: 'State -> array: 'T array -> 'State @@ -1105,6 +1167,8 @@ module Array = /// Text = " 3 -2 -1 0 1" } /// /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val foldBack<'T, 'State> : folder: ('T -> 'State -> 'State) -> array: 'T array -> state: 'State -> 'State @@ -1139,6 +1203,8 @@ module Array = /// /// Evaluates to 1 /// + /// + /// This is an O(n) operation, where n is the length of the arrays. [] val fold2<'T1, 'T2, 'State> : folder: ('State -> 'T1 -> 'T2 -> 'State) -> state: 'State -> array1: 'T1 array -> array2: 'T2 array -> 'State @@ -1188,6 +1254,8 @@ module Array = /// Text = "(-3,1) (-2,2) (-1,3) " } /// /// + /// + /// This is an O(n) operation, where n is the length of the arrays. [] val foldBack2<'T1, 'T2, 'State> : folder: ('T1 -> 'T2 -> 'State -> 'State) -> array1: 'T1 array -> array2: 'T2 array -> state: 'State -> 'State @@ -1221,6 +1289,8 @@ module Array = /// /// Throws IndexOutOfRangeException /// + /// + /// This is an O(1) operation. [] val get: array: 'T array -> index: int -> 'T @@ -1248,6 +1318,8 @@ module Array = /// /// Throws ArgumentException /// + /// + /// This is an O(1) operation. [] val head: array: 'T array -> 'T @@ -1270,6 +1342,8 @@ module Array = /// /// Evaluates to [| (1, [| 1; 3; 5 |]); (0, [| 2; 4 |]) |] /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val groupBy: projection: ('T -> 'Key) -> array: 'T array -> ('Key * 'T array) array when 'Key: equality @@ -1290,6 +1364,8 @@ module Array = /// /// Evaluates to [| (0, "a"); (1, "b"); (2, "c") |] /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val indexed: array: 'T array -> (int * 'T) array @@ -1315,6 +1391,8 @@ module Array = /// /// Throws ArgumentException /// + /// + /// This is an O(n) operation, where n is the count. [] val inline init: count: int -> initializer: (int -> 'T) -> 'T array @@ -1356,6 +1434,8 @@ module Array = /// /// Evaluates to false /// + /// + /// This is an O(1) operation. [] val isEmpty: array: 'T array -> bool @@ -1380,6 +1460,8 @@ module Array = /// /// in the console. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline iter: action: ('T -> unit) -> array: 'T array -> unit @@ -1409,6 +1491,8 @@ module Array = /// /// in the console. /// + /// + /// This is an O(n) operation, where n is the length of the arrays. [] val iter2: action: ('T1 -> 'T2 -> unit) -> array1: 'T1 array -> array2: 'T2 array -> unit @@ -1434,6 +1518,8 @@ module Array = /// /// in the console. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val iteri: action: (int -> 'T -> unit) -> array: 'T array -> unit @@ -1463,6 +1549,8 @@ module Array = /// /// in the console. /// + /// + /// This is an O(n) operation, where n is the length of the arrays. [] val iteri2: action: (int -> 'T1 -> 'T2 -> unit) -> array1: 'T1 array -> array2: 'T2 array -> unit @@ -1488,6 +1576,8 @@ module Array = /// /// Throws ArgumentException /// + /// + /// This is an O(1) operation. [] val inline last: array: 'T array -> 'T @@ -1520,6 +1610,8 @@ module Array = /// /// Throws ArgumentException /// + /// + /// This is an O(1) operation. [] val item: index: int -> array: 'T array -> 'T @@ -1541,6 +1633,8 @@ module Array = /// /// Evaluates to 3 /// + /// + /// This is an O(1) operation. [] val length: array: 'T array -> int @@ -1566,6 +1660,8 @@ module Array = /// /// Evaluates to None /// + /// + /// This is an O(1) operation. [] val tryLast: array: 'T array -> 'T option @@ -1587,6 +1683,8 @@ module Array = /// /// Evaluates to [| 1; 3; 2 |] /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline map: mapping: ('T -> 'U) -> array: 'T array -> 'U array @@ -1613,6 +1711,8 @@ module Array = /// /// Evaluates to [| 'a'; 'd'; 'o' |] /// + /// + /// This is an O(n) operation, where n is the length of the arrays. [] val map2: mapping: ('T1 -> 'T2 -> 'U) -> array1: 'T1 array -> array2: 'T2 array -> 'U array @@ -1643,6 +1743,8 @@ module Array = /// /// Evaluates newCharges to [|In 2; Out 4; In 6|] and balance to 2. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val mapFold<'T, 'State, 'Result> : mapping: ('State -> 'T -> 'Result * 'State) -> state: 'State -> array: 'T array -> 'Result array * 'State @@ -1674,6 +1776,8 @@ module Array = /// /// Evaluates newCharges to [|In 2; Out 4; In 6|] and balance to 2. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val mapFoldBack<'T, 'State, 'Result> : mapping: ('T -> 'State -> 'Result * 'State) -> array: 'T array -> state: 'State -> 'Result array * 'State @@ -1704,6 +1808,8 @@ module Array = /// Evaluates to [| "all"; "the"; "time" |] /// /// + /// + /// This is an O(n) operation, where n is the length of the arrays. [] val map3: mapping: ('T1 -> 'T2 -> 'T3 -> 'U) -> array1: 'T1 array -> array2: 'T2 array -> array3: 'T3 array -> 'U array @@ -1731,6 +1837,8 @@ module Array = /// /// Evaluates to [|(0, 'a'); (1, 'd'); (2, 'o')|] /// + /// + /// This is an O(n) operation, where n is the length of the arrays. [] val mapi2: mapping: (int -> 'T1 -> 'T2 -> 'U) -> array1: 'T1 array -> array2: 'T2 array -> 'U array @@ -1753,6 +1861,8 @@ module Array = /// /// Evaluates to [| 10; 11; 12 |] /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val mapi: mapping: (int -> 'T -> 'U) -> array: 'T array -> 'U array @@ -1784,6 +1894,8 @@ module Array = /// /// Throws System.ArgumentException. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline max: array: 'T array -> 'T when 'T: comparison @@ -1816,6 +1928,8 @@ module Array = /// /// Throws System.ArgumentException. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline maxBy: projection: ('T -> 'U) -> array: 'T array -> 'T when 'U: comparison @@ -1847,6 +1961,8 @@ module Array = /// /// Throws System.ArgumentException. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline min: array: 'T array -> 'T when 'T: comparison @@ -1879,6 +1995,8 @@ module Array = /// /// Throws System.ArgumentException. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline minBy: projection: ('T -> 'U) -> array: 'T array -> 'T when 'U: comparison @@ -1915,6 +2033,8 @@ module Array = /// /// Evaluates to [| 1; 2; 5 |]. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val ofSeq: source: seq<'T> -> 'T array @@ -1936,6 +2056,8 @@ module Array = /// /// Evaluates to [|(1, 2); (2, 3); (3, 4)|]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val pairwise: array: 'T array -> ('T * 'T) array @@ -1959,6 +2081,8 @@ module Array = /// /// Evaluates to ([|2; 4|], [|1; 3|]). /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val partition: predicate: ('T -> bool) -> array: 'T array -> 'T array * 'T array @@ -1981,6 +2105,8 @@ module Array = /// /// Evaluates to [|4; 1; 2; 3|]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val permute: indexMap: (int -> int) -> array: 'T array -> 'T array @@ -2005,6 +2131,8 @@ module Array = /// /// Evaluates to 1342, by computing ((1 * 10 + 3) * 10 + 4) * 10 + 2 /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val reduce: reduction: ('T -> 'T -> 'T) -> array: 'T array -> 'T @@ -2029,6 +2157,8 @@ module Array = /// /// Evaluates to 2431, by computing 1 + (3 + (4 + 2 * 10) * 10) * 10 /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val reduceBack: reduction: ('T -> 'T -> 'T) -> array: 'T array -> 'T @@ -2064,6 +2194,8 @@ module Array = /// /// Evaluates to [| 2; 1; 0 |]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val rev: array: 'T array -> 'T array @@ -2093,6 +2225,8 @@ module Array = /// Evaluates to [|0; 1; -1; 2|]. Note 0 is the initial /// state, 1 the next state, -1 the next state, and 2 the final state. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val scan<'T, 'State> : folder: ('State -> 'T -> 'State) -> state: 'State -> array: 'T array -> 'State array @@ -2122,6 +2256,8 @@ module Array = /// Evaluates to [|2; 1; 3; 0|] by processing each input from back to front. Note 0 is the initial /// state, 3 the next state, 1 the next state, and 2 the final state. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val scanBack<'T, 'State> : folder: ('T -> 'State -> 'State) -> array: 'T array -> state: 'State -> 'State array @@ -2166,6 +2302,8 @@ module Array = /// /// Throws IndexOutOfRangeException /// + /// + /// This is an O(1) operation. [] val set: array: 'T array -> index: int -> value: 'T -> unit @@ -2206,6 +2344,8 @@ module Array = /// /// Evaluates to [| "a"; "b"; "c"; "d" |]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val skip: count: int -> array: 'T array -> 'T array @@ -2228,6 +2368,8 @@ module Array = /// Evaluates to [|"bbb"; "cc"; "d"|] /// /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val skipWhile: predicate: ('T -> bool) -> array: 'T array -> 'T array @@ -2261,6 +2403,8 @@ module Array = /// /// Evaluates to [| 2; 3; 4 |]. /// + /// + /// This is an O(count) operation. [] val sub: array: 'T array -> startIndex: int -> count: int -> 'T array @@ -2283,6 +2427,8 @@ module Array = /// /// Evaluates to [| 1; 1; 3; 4; 6; 8 |]. /// + /// + /// This is an O(n log n) operation, where n is the length of the array. [] val sort: array: 'T array -> 'T array when 'T: comparison @@ -2307,6 +2453,8 @@ module Array = /// /// Evaluates to [|"a"; "dd"; "bbb"; "cccc"|]. /// + /// + /// This is an O(n log n) operation, where n is the length of the array. [] val sortBy: projection: ('T -> 'Key) -> array: 'T array -> 'T array when 'Key: comparison @@ -2335,6 +2483,8 @@ module Array = /// /// Evaluates to [|(0, "aa"); (2, "cc"); (3, "dd"); (1, "bbb")|]. /// + /// + /// This is an O(n log n) operation, where n is the length of the array. [] val sortWith: comparer: ('T -> 'T -> int) -> array: 'T array -> 'T array @@ -2357,6 +2507,8 @@ module Array = /// /// After evaluation array contains [|"a"; "dd"; "bbb"; "cccc"|]. /// + /// + /// This is an O(n log n) operation, modifying the array in place. [] val sortInPlaceBy: projection: ('T -> 'Key) -> array: 'T array -> unit when 'Key: comparison @@ -2380,6 +2532,8 @@ module Array = /// /// After evaluation array contains [|(0, "aa"); (2, "cc"); (3, "dd"); (1, "bbb")|]. /// + /// + /// This is an O(n log n) operation, modifying the array in place. [] val sortInPlaceWith: comparer: ('T -> 'T -> int) -> array: 'T array -> unit @@ -2420,6 +2574,8 @@ module Array = /// /// Evaluates front to [|8; 4; 3|] and back to [|1; 6; 1|]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val splitAt: index: int -> array: 'T array -> ('T array * 'T array) @@ -2440,6 +2596,8 @@ module Array = /// /// Evaluates to [| 8; 6; 4; 3; 1; 1 |]. /// + /// + /// This is an O(n log n) operation, where n is the length of the array. [] val inline sortDescending: array: 'T array -> 'T array when 'T: comparison @@ -2462,6 +2620,8 @@ module Array = /// /// Evaluates to [|"cccc"; "bbb"; "dd"; "a"|]. /// + /// + /// This is an O(n log n) operation, where n is the length of the array. [] val inline sortByDescending: projection: ('T -> 'Key) -> array: 'T array -> 'T array when 'Key: comparison @@ -2501,6 +2661,8 @@ module Array = /// /// Evaluates to 7. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline sumBy: projection: ('T -> ^U) -> array: 'T array -> ^U @@ -2547,6 +2709,8 @@ module Array = /// /// Evaluates to [| |]. /// + /// + /// This is an O(count) operation. [] val take: count: int -> array: 'T array -> 'T array @@ -2569,6 +2733,8 @@ module Array = /// Evaluates to [| "a"; "bb" |] /// /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val takeWhile: predicate: ('T -> bool) -> array: 'T array -> 'T array @@ -2590,6 +2756,8 @@ module Array = /// Evaluates to [| "bb"; "ccc" |] /// /// + /// + /// This is an O(n) operation, creating a new array. [] val tail: array: 'T array -> 'T array @@ -2628,6 +2796,8 @@ module Array = /// /// Evaluates to seq { 1; 2; 5 }. /// + /// + /// This is an O(1) operation. [] val toSeq: array: 'T array -> seq<'T> @@ -2650,6 +2820,8 @@ module Array = /// /// Evaluates to [|[|10; 11|]; [|20; 21|]; [|30; 31|]|]. /// + /// + /// This is an O(n*m) operation, where n and m are the dimensions. [] val transpose: arrays: seq<'T array> -> 'T array array @@ -2688,6 +2860,8 @@ module Array = /// /// Evaluates to [| |]. /// + /// + /// This is an O(count) operation. [] val truncate: count: int -> array: 'T array -> 'T array @@ -2718,6 +2892,8 @@ module Array = /// /// Evaluates to None /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val tryFind: predicate: ('T -> bool) -> array: 'T array -> 'T option @@ -2748,6 +2924,8 @@ module Array = /// /// Evaluates to None /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val tryFindBack: predicate: ('T -> bool) -> array: 'T array -> 'T option @@ -2778,6 +2956,8 @@ module Array = /// /// Evaluates to None /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val tryFindIndex: predicate: ('T -> bool) -> array: 'T array -> int option @@ -2808,6 +2988,8 @@ module Array = /// /// Evaluates to None. /// + /// + /// This is an O(1) operation. [] val tryItem: index: int -> array: 'T array -> 'T option @@ -2838,6 +3020,8 @@ module Array = /// /// Evaluates to None /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val tryFindIndexBack: predicate: ('T -> bool) -> array: 'T array -> int option @@ -2876,6 +3060,8 @@ module Array = /// /// Evaluates numbers to [|1; 2|] and names to [|"one"; "two"|]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val unzip: array: ('T1 * 'T2) array -> ('T1 array * 'T2 array) @@ -2918,6 +3104,8 @@ module Array = /// /// Evaluates to [| 2; 4 |] /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val where: predicate: ('T -> bool) -> array: 'T array -> 'T array @@ -2940,6 +3128,8 @@ module Array = /// /// Evaluates to [|[|1; 2; 3|]; [|2; 3; 4|]; [|3; 4; 5|]|] /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val windowed: windowSize: int -> array: 'T array -> 'T array array @@ -2963,6 +3153,8 @@ module Array = /// /// Evaluates to [| (1, "one"); (2, "two") |]. /// + /// + /// This is an O(n) operation, where n is the length of the arrays. [] val zip: array1: 'T1 array -> array2: 'T2 array -> ('T1 * 'T2) array @@ -2988,6 +3180,8 @@ module Array = /// /// Evaluates to [|(1, "one", "I"); (2, "two", "II")|]. /// + /// + /// This is an O(n) operation, where n is the length of the arrays. [] val zip3: array1: 'T1 array -> array2: 'T2 array -> array3: 'T3 array -> ('T1 * 'T2 * 'T3) array @@ -3008,6 +3202,8 @@ module Array = /// /// Evaluates to [| 0; 2 |]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val removeAt: index: int -> source: 'T array -> 'T array @@ -3029,6 +3225,8 @@ module Array = /// /// Evaluates to [| 0; 3 |]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val removeManyAt: index: int -> count: int -> source: 'T array -> 'T array @@ -3050,6 +3248,8 @@ module Array = /// /// Evaluates to [| 0; 9; 2 |]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val updateAt: index: int -> value: 'T -> source: 'T array -> 'T array @@ -3071,6 +3271,8 @@ module Array = /// /// Evaluates to [| 0; 9; 1; 2 |]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val insertAt: index: int -> value: 'T -> source: 'T array -> 'T array @@ -3092,6 +3294,8 @@ module Array = /// /// Evaluates to [| 0; 8; 9; 1; 2 |]. /// + /// + /// This is an O(n+m) operation, where n is the length of the array and m is the number of elements to insert. [] val insertManyAt: index: int -> values: seq<'T> -> source: 'T array -> 'T array @@ -3442,6 +3646,8 @@ module Array = /// [1; 2] |> Array.Parallel.forall isEven // evaluates to false /// /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val forall: predicate: ('T -> bool) -> array: 'T array -> bool @@ -3475,6 +3681,8 @@ module Array = /// /// Evaluates to false /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val exists: predicate: ('T -> bool) -> array: 'T array -> bool @@ -3505,6 +3713,8 @@ module Array = /// /// Evaluates to None /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val tryFind: predicate: ('T -> bool) -> array: 'T array -> 'T option @@ -3535,6 +3745,8 @@ module Array = /// /// Evaluates to None /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val tryFindIndex: predicate: ('T -> bool) -> array: 'T array -> int option @@ -3567,6 +3779,8 @@ module Array = /// Evaluates to None. /// /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the array. [] val tryPick: chooser: ('T -> 'U option) -> array: 'T array -> 'U option @@ -3594,6 +3808,8 @@ module Array = /// Evaluates to 1 + 3 + 4 + 2. However, the system could have decided to compute (1+3) and (4+2) first, and then put them together. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline reduce: reduction: ('T -> 'T -> 'T) -> array: 'T array -> 'T @@ -3652,6 +3868,8 @@ module Array = /// /// Throws System.ArgumentException. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline max: array: 'T array -> 'T when 'T: comparison @@ -3684,6 +3902,8 @@ module Array = /// /// Throws System.ArgumentException. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline maxBy: projection: ('T -> 'U) -> array: 'T array -> 'T when 'U: comparison @@ -3715,6 +3935,8 @@ module Array = /// /// Throws System.ArgumentException. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline min: array: 'T array -> 'T when 'T: comparison @@ -3747,6 +3969,8 @@ module Array = /// /// Throws System.ArgumentException. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline minBy: projection: ('T -> 'U) -> array: 'T array -> 'T when 'U: comparison @@ -3787,6 +4011,8 @@ module Array = /// /// Evaluates to 7. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline sumBy: projection: ('T -> ^U) -> array: 'T array -> ^U @@ -3814,6 +4040,8 @@ module Array = /// /// Throws ArgumentException /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline average: array: ^T array -> ^T @@ -3851,6 +4079,8 @@ module Array = /// /// Throws ArgumentException /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline averageBy: projection: ('T -> ^U) -> array: 'T array -> ^U @@ -3887,6 +4117,8 @@ module Array = /// /// Evaluates to [| 2 |] /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val choose: chooser: ('T -> 'U option) -> array: 'T array -> 'U array @@ -3921,6 +4153,8 @@ module Array = /// /// Evaluates to [| 1; 2; 3; 4 |] /// + /// + /// This is an O(n) operation, where n is the total output length. [] val collect: mapping: ('T -> 'U array) -> array: 'T array -> 'U array @@ -3945,6 +4179,8 @@ module Array = /// /// Evaluates to [| 1; 3; 2 |] /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val map: mapping: ('T -> 'U) -> array: 'T array -> 'U array @@ -3970,6 +4206,8 @@ module Array = /// /// Evaluates to [| 10; 11; 12 |] /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val mapi: mapping: (int -> 'T -> 'U) -> array: 'T array -> 'U array @@ -3996,6 +4234,8 @@ module Array = /// Evaluates to [| (1, [| 1; 3; 5 |]); (0, [| 2; 4 |]) |] /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val groupBy: projection: ('T -> 'Key) -> array: 'T array -> ('Key * 'T array) array when 'Key: equality @@ -4022,6 +4262,8 @@ module Array = /// b /// /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val iter: action: ('T -> unit) -> array: 'T array -> unit @@ -4049,6 +4291,8 @@ module Array = /// 1: b /// /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val iteri: action: (int -> 'T -> unit) -> array: 'T array -> unit @@ -4093,6 +4337,8 @@ module Array = /// /// Evaluates to ([|2; 4|], [|1; 3|]). /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val partition: predicate: ('T -> bool) -> array: 'T array -> 'T array * 'T array @@ -4115,6 +4361,8 @@ module Array = /// /// Evaluates to [| 1; 1 3; 4; 6; 8 |]. /// + /// + /// This is an O(n log n) operation, where n is the length of the array. [] val sort: array: 'T array -> 'T array when 'T: comparison @@ -4140,6 +4388,8 @@ module Array = /// Evaluates to [|"a"; "dd"; "bbb"; "cccc"|]. /// + /// + /// This is an O(n log n) operation, where n is the length of the array. [] val sortBy: projection: ('T -> 'Key) -> array: 'T array -> 'T array when 'Key: comparison @@ -4168,6 +4418,8 @@ module Array = /// /// Evaluates to [|(0, "aa"); (2, "cc"); (3, "dd"); (1, "bbb")|]. /// + /// + /// This is an O(n log n) operation, where n is the length of the array. [] val sortWith: comparer: ('T -> 'T -> int) -> array: 'T array -> 'T array @@ -4190,6 +4442,8 @@ module Array = /// /// After evaluation array contains [|"a"; "dd"; "bbb"; "cccc"|]. /// + /// + /// This is an O(n log n) operation, modifying the array in place. [] val sortInPlaceBy: projection: ('T -> 'Key) -> array: 'T array -> unit when 'Key: comparison @@ -4213,6 +4467,8 @@ module Array = /// /// After evaluation array contains [|(0, "aa"); (2, "cc"); (3, "dd"); (1, "bbb")|]. /// + /// + /// This is an O(n log n) operation, modifying the array in place. [] val sortInPlaceWith: comparer: ('T -> 'T -> int) -> array: 'T array -> unit @@ -4251,6 +4507,8 @@ module Array = /// /// Evaluates to [| 8; 6; 4; 3; 1; 1 |]. /// + /// + /// This is an O(n log n) operation, where n is the length of the array. [] val sortDescending: array: 'T array -> 'T array when 'T: comparison @@ -4273,6 +4531,8 @@ module Array = /// /// Evaluates to [|"cccc"; "bbb"; "dd"; "a"|]. /// + /// + /// This is an O(n log n) operation, where n is the length of the array. [] val sortByDescending: projection: ('T -> 'Key) -> array: 'T array -> 'T array when 'Key: comparison @@ -4296,6 +4556,8 @@ module Array = /// /// Evaluates to [| (1, "one"); (2, "two") |]. /// + /// + /// This is an O(n) operation, where n is the length of the arrays. [] val zip: array1: 'T1 array -> array2: 'T2 array -> ('T1 * 'T2) array @@ -4317,5 +4579,7 @@ module Array = /// /// Evaluates to [| 2; 4 |] /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val filter: predicate: ('T -> bool) -> array: 'T array -> 'T array diff --git a/src/FSharp.Core/seq.fsi b/src/FSharp.Core/seq.fsi index 8aedfa6ff6d..67798d9aadf 100644 --- a/src/FSharp.Core/seq.fsi +++ b/src/FSharp.Core/seq.fsi @@ -30,6 +30,8 @@ module Seq = /// seq { (1, 3); (1, 4); (2, 3); (2, 4) } /// /// + /// + /// Enumeration is O(n*m), where n and m are the lengths of the sequences. [] val allPairs: source1: seq<'T1> -> source2: seq<'T2> -> seq<'T1 * 'T2> @@ -54,6 +56,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 1; 2; 3; 4 } /// + /// + /// Sequence construction is O(1). Enumeration is O(n+m), where n and m are the lengths of the sequences. [] val append: source1: seq<'T> -> source2: seq<'T> -> seq<'T> @@ -82,6 +86,8 @@ module Seq = /// /// Throws ArgumentException /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val inline average: source: seq< ^T > -> ^T @@ -122,6 +128,8 @@ module Seq = /// /// Throws ArgumentException /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val inline averageBy: projection: ('T -> ^U) -> source: seq<'T> -> ^U @@ -169,6 +177,8 @@ module Seq = /// Evaluates to a sequence yielding the same results as seq { 1; 2; 3 }, /// and it will not do the calculation again when called. /// + /// + /// Caching requires O(k) space for k accessed elements. [] val cache: source: seq<'T> -> seq<'T> @@ -191,6 +201,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 1; 2; 3 }, explicitly typed as seq<int>. /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val cast: source: IEnumerable -> seq<'T> @@ -222,6 +234,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 2 } /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val choose: chooser: ('T -> 'U option) -> source: seq<'T> -> seq<'U> @@ -248,6 +262,8 @@ module Seq = /// /// Throws ArgumentException /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val chunkBySize: chunkSize: int -> source: seq<'T> -> seq<'T array> @@ -283,6 +299,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 1; 2; 3; 4 } /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val collect: mapping: ('T -> 'Collection) -> source: seq<'T> -> seq<'U> when 'Collection :> seq<'U> @@ -364,6 +382,8 @@ module Seq = /// /// Evaluates to -1 /// + /// + /// This is an O(min(n,m)) operation, where n and m are the lengths of the sequences. [] val compareWith: comparer: ('T -> 'T -> int) -> source1: seq<'T> -> source2: seq<'T> -> int @@ -387,6 +407,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 1; 2; 3; 4; 5 } /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the total number of elements. [] val concat: sources: seq<'Collection> -> seq<'T> when 'Collection :> seq<'T> @@ -434,6 +456,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { ("a", 2); ("b", 1) } /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val countBy: projection: ('T -> 'Key) -> source: seq<'T> -> seq<'Key * int> when 'Key: equality @@ -472,6 +496,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 1; 2; 3 } /// + /// + /// This operation requires O(k) space where k is the number of distinct elements seen. [] val distinct: source: seq<'T> -> seq<'T> when 'T: equality @@ -494,6 +520,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { { Bar = 1 }; { Bar = 2 }; { Bar = 3 } } /// + /// + /// This operation requires O(k) space where k is the number of distinct keys seen. [] val distinctBy: projection: ('T -> 'Key) -> source: seq<'T> -> seq<'T> when 'Key: equality @@ -529,6 +557,8 @@ module Seq = /// /// Throws ArgumentException /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val splitInto: count: int -> source: seq<'T> -> seq<'T array> @@ -570,6 +600,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 2; 4 } /// + /// + /// This is an O(n+m) operation using hash-based exclusion. [] val except: itemsToExclude: seq<'T> -> source: seq<'T> -> seq<'T> when 'T: equality @@ -603,6 +635,8 @@ module Seq = /// /// Evaluates to false /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val exists: predicate: ('T -> bool) -> source: seq<'T> -> bool @@ -640,6 +674,8 @@ module Seq = /// /// Evaluates to true /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the sequences. [] val exists2: predicate: ('T1 -> 'T2 -> bool) -> source1: seq<'T1> -> source2: seq<'T2> -> bool @@ -666,6 +702,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 2; 4 } /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val filter: predicate: ('T -> bool) -> source: seq<'T> -> seq<'T> @@ -692,6 +730,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 2; 4 } /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val where: predicate: ('T -> bool) -> source: seq<'T> -> seq<'T> @@ -723,6 +763,8 @@ module Seq = /// /// Throws KeyNotFoundException /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val find: predicate: ('T -> bool) -> source: seq<'T> -> 'T @@ -757,6 +799,8 @@ module Seq = /// /// Throws KeyNotFoundException /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val findBack: predicate: ('T -> bool) -> source: seq<'T> -> 'T @@ -787,6 +831,8 @@ module Seq = /// /// Throws KeyNotFoundException /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val findIndex: predicate: ('T -> bool) -> source: seq<'T> -> int @@ -821,6 +867,8 @@ module Seq = /// /// Throws KeyNotFoundException /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val findIndexBack: predicate: ('T -> bool) -> source: seq<'T> -> int @@ -851,6 +899,8 @@ module Seq = /// /// Evaluates to 2 /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val fold<'T, 'State> : folder: ('State -> 'T -> 'State) -> state: 'State -> source: seq<'T> -> 'State @@ -886,6 +936,8 @@ module Seq = /// /// Evaluates to 1 /// + /// + /// This is an O(n) operation, where n is the length of the sequences. [] val fold2<'T1, 'T2, 'State> : folder: ('State -> 'T1 -> 'T2 -> 'State) -> state: 'State -> source1: seq<'T1> -> source2: seq<'T2> -> 'State @@ -932,6 +984,8 @@ module Seq = /// Text = " 3 -2 -1 0 1" } /// /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val foldBack<'T, 'State> : folder: ('T -> 'State -> 'State) -> source: seq<'T> -> state: 'State -> 'State @@ -984,6 +1038,8 @@ module Seq = /// Text = " (-3,1) (-2,2) (-1,3)" } /// /// + /// + /// This is an O(n) operation, where n is the length of the sequences. [] val foldBack2<'T1, 'T2, 'State> : folder: ('T1 -> 'T2 -> 'State -> 'State) -> source1: seq<'T1> -> source2: seq<'T2> -> state: 'State -> 'State @@ -1010,6 +1066,8 @@ module Seq = /// [1; 2] |> Seq.forall isEven // evaluates to false /// /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val forall: predicate: ('T -> bool) -> source: seq<'T> -> bool @@ -1044,6 +1102,8 @@ module Seq = /// /// Evaluates to false. /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the sequences. [] val forall2: predicate: ('T1 -> 'T2 -> bool) -> source1: seq<'T1> -> source2: seq<'T2> -> bool @@ -1069,6 +1129,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { (1, seq { 1; 3; 5 }); (0, seq { 2; 4 }) } /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val groupBy: projection: ('T -> 'Key) -> source: seq<'T> -> seq<'Key * seq<'T>> when 'Key: equality @@ -1096,6 +1158,8 @@ module Seq = /// /// Throws ArgumentException /// + /// + /// This is an O(1) operation. [] val head: source: seq<'T> -> 'T @@ -1120,6 +1184,8 @@ module Seq = /// /// Evaluates to None /// + /// + /// This is an O(1) operation. [] val tryHead: source: seq<'T> -> 'T option @@ -1145,6 +1211,8 @@ module Seq = /// /// Throws ArgumentException /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val last: source: seq<'T> -> 'T @@ -1170,6 +1238,8 @@ module Seq = /// /// Evaluates to None /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val tryLast: source: seq<'T> -> 'T option @@ -1206,6 +1276,8 @@ module Seq = /// /// Throws ArgumentException /// + /// + /// This is an O(1) operation. [] val exactlyOne: source: seq<'T> -> 'T @@ -1241,6 +1313,8 @@ module Seq = /// /// Evaluates to None /// + /// + /// This is an O(1) operation. [] val tryExactlyOne: source: seq<'T> -> 'T option @@ -1265,6 +1339,8 @@ module Seq = /// /// Evaluates to false /// + /// + /// This is an O(1) operation. [] val isEmpty: source: seq<'T> -> bool @@ -1314,6 +1390,8 @@ module Seq = /// /// Throws ArgumentException /// + /// + /// This is an O(n) operation, where n is the count. [] val init: count: int -> initializer: (int -> 'T) -> seq<'T> @@ -1337,6 +1415,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 5; 6; 7; 8; ... } /// + /// + /// This is an O(1) operation. [] val initInfinite: initializer: (int -> 'T) -> seq<'T> @@ -1367,6 +1447,8 @@ module Seq = /// /// Throws ArgumentException /// + /// + /// This is an O(n) operation, where n is the index. [] val item: index: int -> source: seq<'T> -> 'T @@ -1389,6 +1471,8 @@ module Seq = /// /// in the console. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val iter: action: ('T -> unit) -> source: seq<'T> -> unit @@ -1415,6 +1499,8 @@ module Seq = /// /// in the console. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val iteri: action: (int -> 'T -> unit) -> source: seq<'T> -> unit @@ -1442,6 +1528,8 @@ module Seq = /// /// in the console. /// + /// + /// This is an O(n) operation, where n is the length of the sequences. [] val iter2: action: ('T1 -> 'T2 -> unit) -> source1: seq<'T1> -> source2: seq<'T2> -> unit @@ -1470,6 +1558,8 @@ module Seq = /// /// in the console. /// + /// + /// This is an O(n) operation, where n is the length of the sequences. [] val iteri2: action: (int -> 'T1 -> 'T2 -> unit) -> source1: seq<'T1> -> source2: seq<'T2> -> unit @@ -1515,6 +1605,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 1; 3; 2 } /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val map: mapping: ('T -> 'U) -> source: seq<'T> -> seq<'U> @@ -1539,6 +1631,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 'a'; 'd'; 'o' } /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequences. [] val map2: mapping: ('T1 -> 'T2 -> 'U) -> source1: seq<'T1> -> source2: seq<'T2> -> seq<'U> @@ -1572,6 +1666,8 @@ module Seq = /// /// Evaluates newCharges to seq { In 2; Out 4; In 6 } and balance to 2. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val mapFold<'T, 'State, 'Result> : mapping: ('State -> 'T -> 'Result * 'State) -> state: 'State -> source: seq<'T> -> seq<'Result> * 'State @@ -1606,6 +1702,8 @@ module Seq = /// /// Evaluates newCharges to seq { In 2; Out 4; In 6 } and balance to 2. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val mapFoldBack<'T, 'State, 'Result> : mapping: ('T -> 'State -> 'Result * 'State) -> source: seq<'T> -> state: 'State -> seq<'Result> * 'State @@ -1634,6 +1732,8 @@ module Seq = /// Evaluates to a sequence yielding the same results as seq { "all"; "the"; "time" } /// /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequences. [] val map3: mapping: ('T1 -> 'T2 -> 'T3 -> 'U) -> source1: seq<'T1> -> source2: seq<'T2> -> source3: seq<'T3> -> seq<'U> @@ -1657,6 +1757,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 10; 11; 12 } /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val mapi: mapping: (int -> 'T -> 'U) -> source: seq<'T> -> seq<'U> @@ -1682,6 +1784,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { (0, 'a'); (1, 'd'); (2, 'o') } /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequences. [] val mapi2: mapping: (int -> 'T1 -> 'T2 -> 'U) -> source1: seq<'T1> -> source2: seq<'T2> -> seq<'U> @@ -1711,6 +1815,8 @@ module Seq = /// /// Throws System.ArgumentException. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val inline max: source: seq<'T> -> 'T when 'T: comparison @@ -1741,6 +1847,8 @@ module Seq = /// /// Throws System.ArgumentException. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val inline maxBy: projection: ('T -> 'U) -> source: seq<'T> -> 'T when 'U: comparison @@ -1770,6 +1878,8 @@ module Seq = /// /// Throws System.ArgumentException. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val inline min: source: seq<'T> -> 'T when 'T: comparison @@ -1800,6 +1910,8 @@ module Seq = /// /// Throws System.ArgumentException. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val inline minBy: projection: ('T -> 'U) -> source: seq<'T> -> 'T when 'U: comparison @@ -1832,6 +1944,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 1; 2; 5 }. /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the array. [] val ofArray: source: 'T array -> seq<'T> @@ -1870,6 +1984,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { (1, 2); (2, 3); (3, 4) }. /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val pairwise: source: seq<'T> -> seq<'T * 'T> @@ -1894,6 +2010,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 4; 1; 2; 3 }. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val permute: indexMap: (int -> int) -> source: seq<'T> -> seq<'T> @@ -1927,6 +2045,8 @@ module Seq = /// Throws KeyNotFoundException. /// /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val pick: chooser: ('T -> 'U option) -> source: seq<'T> -> 'U @@ -1960,6 +2080,8 @@ module Seq = /// /// Throws an InvalidCastException. /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val readonly: source: seq<'T> -> seq<'T> @@ -1985,6 +2107,8 @@ module Seq = /// /// Evaluates to 1342, by computing ((1 * 10 + 3) * 10 + 4) * 10 + 2 /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val reduce: reduction: ('T -> 'T -> 'T) -> source: seq<'T> -> 'T @@ -2027,6 +2151,8 @@ module Seq = /// /// Evaluates to 2431, by computing 1 + (3 + (4 + 2 * 10) * 10) * 10 /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val reduceBack: reduction: ('T -> 'T -> 'T) -> source: seq<'T> -> 'T @@ -2048,6 +2174,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 2; 1; 0 }. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val rev: source: seq<'T> -> seq<'T> @@ -2077,6 +2205,8 @@ module Seq = /// Evaluates to a sequence yielding the same results as seq { 0; 1; -1; 2 }. Note 0 is the initial /// state, 1 the next state, -1 the next state, and 2 the final state. /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val scan<'T, 'State> : folder: ('State -> 'T -> 'State) -> state: 'State -> source: seq<'T> -> seq<'State> @@ -2126,6 +2256,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 7 }. /// + /// + /// This is an O(1) operation. [] val singleton: value: 'T -> seq<'T> @@ -2167,6 +2299,8 @@ module Seq = /// /// Evaluates a sequence yielding the same results as seq { "a"; "b"; "c"; "d" }. /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the count. [] val skip: count: int -> source: seq<'T> -> seq<'T> @@ -2188,6 +2322,8 @@ module Seq = /// /// Evaluates a sequence yielding the same results as seq { "bbb"; "cc"; "d" } /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val skipWhile: predicate: ('T -> bool) -> source: seq<'T> -> seq<'T> @@ -2214,6 +2350,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 1; 1 3; 4; 6; 8 }. /// + /// + /// This is an O(n log n) operation, where n is the length of the sequence. [] val sort: source: seq<'T> -> seq<'T> when 'T: comparison @@ -2244,6 +2382,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { (0, "aa"); (2, "cc"); (3, "dd"); (1, "bbb") }. /// + /// + /// This is an O(n log n) operation, where n is the length of the sequence. [] val sortWith: comparer: ('T -> 'T -> int) -> source: seq<'T> -> seq<'T> @@ -2272,6 +2412,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { "a"; "dd"; "bbb"; "cccc" }. /// + /// + /// This is an O(n log n) operation, where n is the length of the sequence. [] val sortBy: projection: ('T -> 'Key) -> source: seq<'T> -> seq<'T> when 'Key: comparison @@ -2298,6 +2440,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 8; 6; 4; 3; 1; 1 }. /// + /// + /// This is an O(n log n) operation, where n is the length of the sequence. [] val inline sortDescending: source: seq<'T> -> seq<'T> when 'T: comparison @@ -2326,6 +2470,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { "cccc"; "bbb"; "dd"; "a" }. /// + /// + /// This is an O(n log n) operation, where n is the length of the sequence. [] val inline sortByDescending: projection: ('T -> 'Key) -> source: seq<'T> -> seq<'T> when 'Key: comparison @@ -2365,6 +2511,8 @@ module Seq = /// /// Evaluates to 7. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val inline sumBy: projection: ('T -> ^U) -> source: seq<'T> -> ^U @@ -2389,6 +2537,8 @@ module Seq = /// Evaluates to a sequence yielding the same results as seq { "bb"; "ccc" } /// /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val tail: source: seq<'T> -> seq<'T> @@ -2434,6 +2584,8 @@ module Seq = /// /// Evaluates to a sequence yielding no results. /// + /// + /// Sequence construction is O(1). Enumeration is O(count). [] val take: count: int -> source: seq<'T> -> seq<'T> @@ -2455,6 +2607,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { "a"; "bb" } /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val takeWhile: predicate: ('T -> bool) -> source: seq<'T> -> seq<'T> @@ -2493,6 +2647,8 @@ module Seq = /// /// Evaluates to [ 1; 2; 5 ]. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val toList: source: seq<'T> -> 'T list @@ -2523,6 +2679,8 @@ module Seq = /// /// Evaluates to None /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val tryFind: predicate: ('T -> bool) -> source: seq<'T> -> 'T option @@ -2556,6 +2714,8 @@ module Seq = /// /// Evaluates to None /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val tryFindBack: predicate: ('T -> bool) -> source: seq<'T> -> 'T option @@ -2586,6 +2746,8 @@ module Seq = /// /// Evaluates to None /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val tryFindIndex: predicate: ('T -> bool) -> source: seq<'T> -> int option @@ -2615,6 +2777,8 @@ module Seq = /// /// Evaluates to None. /// + /// + /// This is an O(n) operation, where n is the index. [] val tryItem: index: int -> source: seq<'T> -> 'T option @@ -2648,6 +2812,8 @@ module Seq = /// /// Evaluates to None /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val tryFindIndexBack: predicate: ('T -> bool) -> source: seq<'T> -> int option @@ -2678,6 +2844,8 @@ module Seq = /// /// Evaluates to None. /// + /// + /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val tryPick: chooser: ('T -> 'U option) -> source: seq<'T> -> 'U option @@ -2703,6 +2871,8 @@ module Seq = /// /// Evaluates to a sequence of sequences yielding the same results as [ [10; 11]; [20; 21]; [30; 31] ]. /// + /// + /// This is an O(n*m) operation, where n and m are the dimensions. [] val transpose: source: seq<'Collection> -> seq> when 'Collection :> seq<'T> @@ -2741,6 +2911,8 @@ module Seq = /// /// Evaluates to the empty sequence. /// + /// + /// Sequence construction is O(1). Enumeration is O(count). [] val truncate: count: int -> source: seq<'T> -> seq<'T> @@ -2771,6 +2943,8 @@ module Seq = /// /// Evaluates to an infinite sequence yielding the results seq { 1I; 2I; 4I; 8I; ... } /// + /// + /// This is an O(n) operation, where n is the number of elements generated. [] val unfold: generator: ('State -> ('T * 'State) option) -> state: 'State -> seq<'T> @@ -2792,6 +2966,8 @@ module Seq = /// /// Evaluates to a sequence of arrays yielding the results seq { [| 1; 2; 3 |]; [| 2; 3; 4 |]; [| 3; 4; 5 |] } /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val windowed: windowSize: int -> source: seq<'T> -> seq<'T array> @@ -2815,6 +2991,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { (1, "one"); (2, "two") }. /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequences. [] val zip: source1: seq<'T1> -> source2: seq<'T2> -> seq<'T1 * 'T2> @@ -2840,6 +3018,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { (1, "one", "I"); (2, "two", "II") }. /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequences. [] val zip3: source1: seq<'T1> -> source2: seq<'T2> -> source3: seq<'T3> -> seq<'T1 * 'T2 * 'T3> @@ -2877,6 +3057,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 0; 3 }. /// + /// + /// This is an O(n) operation, where n is the index. [] val removeManyAt: index: int -> count: int -> source: seq<'T> -> seq<'T> @@ -2915,6 +3097,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 0; 9; 1; 2 }. /// + /// + /// This is an O(n) operation, where n is the index. [] val insertAt: index: int -> value: 'T -> source: seq<'T> -> seq<'T> From 471dff89e010e4788256f1dba485e1a7d1728718 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jan 2026 19:08:37 +0100 Subject: [PATCH 06/17] Add complexity remarks to all random* functions in List module Added O(n) complexity documentation to 12 random* functions: - randomShuffle, randomShuffleWith, randomShuffleBy: O(n) - randomChoice, randomChoiceWith, randomChoiceBy: O(n) - randomChoices, randomChoicesWith, randomChoicesBy: O(n * count) - randomSample, randomSampleWith, randomSampleBy: O(n) All 117 List module functions now have complexity remarks. Build and XML validation tests pass. --- src/FSharp.Core/list.fsi | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/FSharp.Core/list.fsi b/src/FSharp.Core/list.fsi index 9912afdfbd2..9218eeed5ec 100644 --- a/src/FSharp.Core/list.fsi +++ b/src/FSharp.Core/list.fsi @@ -2885,6 +2885,8 @@ module List = /// Can evaluate to [ 0; 2; 4; 3; 1 ]. /// /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val randomShuffle : source: 'T list -> 'T list @@ -2905,6 +2907,8 @@ module List = /// /// Can evaluate to [ 0; 2; 4; 3; 1 ]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val randomShuffleWith : random: Random -> source: 'T list -> 'T list @@ -2925,6 +2929,8 @@ module List = /// /// Can evaluate to [ 0; 2; 4; 3; 1 ]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val randomShuffleBy : randomizer: (unit -> float) -> source: 'T list -> 'T list @@ -2944,6 +2950,8 @@ module List = /// /// Can evaluate to 3. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val randomChoice : source: 'T list -> 'T @@ -2965,6 +2973,8 @@ module List = /// /// Can evaluate to 3. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val randomChoiceWith : random: Random -> source: 'T list -> 'T @@ -2986,6 +2996,8 @@ module List = /// /// Can evaluate to 3. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val randomChoiceBy : randomizer: (unit -> float) -> source: 'T list -> 'T @@ -3007,6 +3019,8 @@ module List = /// /// Can evaluate to [ 3; 1; 3 ]. /// + /// + /// This is an O(n * count) operation, where n is the length of the list. [] val randomChoices : count: int -> source: 'T list -> 'T list @@ -3030,6 +3044,8 @@ module List = /// /// Can evaluate to [ 3; 1; 3 ]. /// + /// + /// This is an O(n * count) operation, where n is the length of the list. [] val randomChoicesWith : random: Random -> count: int -> source: 'T list -> 'T list @@ -3054,6 +3070,8 @@ module List = /// /// Can evaluate to [ 3; 1; 3 ]. /// + /// + /// This is an O(n * count) operation, where n is the length of the list. [] val randomChoicesBy : randomizer: (unit -> float) -> count: int -> source: 'T list -> 'T list @@ -3076,6 +3094,8 @@ module List = /// /// Can evaluate to [ 3; 1; 2 ]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val randomSample : count: int -> source: 'T list -> 'T list @@ -3100,6 +3120,8 @@ module List = /// /// Can evaluate to [ 3; 1; 2 ]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val randomSampleWith : random: Random -> count: int -> source: 'T list -> 'T list @@ -3124,5 +3146,7 @@ module List = /// /// Can evaluate to [ 3; 1; 2 ]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val randomSampleBy : randomizer: (unit -> float) -> count: int -> source: 'T list -> 'T list \ No newline at end of file From dc02e23e759a6d355bde4e20bcb02fcebb1231c7 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jan 2026 19:34:04 +0100 Subject: [PATCH 07/17] Add complexity documentation to all 164 Array module functions - Fixed 43 duplicate tags by merging complexity into existing remarks - Added missing complexity remarks to 33 functions including all random* functions - Fixed misplaced remark for Array.empty (between attributes) - All 164 val declarations now have O(...) complexity in - Build: 0 warnings, 0 errors - XmlDocumentationValidation test: 1 passed, 0 failed --- src/FSharp.Core/array.fsi | 233 +++++++++++++++++--------------------- 1 file changed, 104 insertions(+), 129 deletions(-) diff --git a/src/FSharp.Core/array.fsi b/src/FSharp.Core/array.fsi index 9a517fa5063..e3821fc8a5b 100644 --- a/src/FSharp.Core/array.fsi +++ b/src/FSharp.Core/array.fsi @@ -53,6 +53,8 @@ module Array = /// /// Evaluates to [| 1; 2; 3; 4 |]. /// + /// + /// This is an O(n+m) operation, where n and m are the lengths of the arrays. [] val append: array1: 'T array -> array2: 'T array -> 'T array @@ -143,7 +145,7 @@ module Array = /// let target = [| 0; 1; 2; 3; 4; 5 |] /// target[3..4] <- source[1..2] /// - /// + /// This is an O(count) operation. /// /// Thrown when either of the input arrays is null. /// Thrown when any of sourceIndex, targetIndex or count are negative, @@ -158,8 +160,6 @@ module Array = /// /// After evaluation target contains [| 0; 1; 2; 13; 14; 5 |]. /// - /// - /// This is an O(count) operation. [] val inline blit: source: 'T array -> sourceIndex: int -> target: 'T array -> targetIndex: int -> count: int -> unit @@ -297,6 +297,8 @@ module Array = /// /// Evaluates to [| 1; 2; 3; 4; 5 |] /// + /// + /// This is an O(n) operation, where n is the total number of elements across all arrays. [] val concat: arrays: seq<'T array> -> 'T array @@ -336,6 +338,8 @@ module Array = /// /// Evaluates to a new array containing[| 12; 13; 14 |]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val copy: array: 'T array -> 'T array @@ -673,6 +677,8 @@ module Array = /// Array.empty // Evaluates to [| |] /// /// + /// + /// This is an O(1) operation. [] [] val empty<'T> : 'T array @@ -785,7 +791,7 @@ module Array = /// /// The predicate is applied to the elements of the input array. If any application /// returns true then the overall result is true and no further elements are tested. - /// Otherwise, false is returned. + /// Otherwise, false is returned. This is an O(n) operation in the worst case, where n is the length of the array. /// /// The function to test the input elements. /// The input array. @@ -811,8 +817,6 @@ module Array = /// /// Evaluates to false /// - /// - /// This is an O(n) operation in the worst case, where n is the length of the array. [] val inline exists: predicate: ('T -> bool) -> array: 'T array -> bool @@ -822,7 +826,7 @@ module Array = /// two lengths of the collections. If any application returns true then the overall result is /// true and no further elements are tested. Otherwise, if one collections is longer /// than the other then the ArgumentException exception is raised. - /// Otherwise, false is returned. + /// Otherwise, false is returned. This is an O(n) operation in the worst case, where n is the length of the arrays. /// /// The function to test the input elements. /// The first input array. @@ -852,8 +856,6 @@ module Array = /// /// Evaluates to true /// - /// - /// This is an O(n) operation in the worst case, where n is the length of the arrays. [] val exists2: predicate: ('T1 -> 'T2 -> bool) -> array1: 'T1 array -> array2: 'T2 array -> bool @@ -1021,7 +1023,7 @@ module Array = /// /// The predicate is applied to the elements of the input collection. If any application /// returns false then the overall result is false and no further elements are tested. - /// Otherwise, true is returned. + /// Otherwise, true is returned. This is an O(n) operation in the worst case, where n is the length of the array. /// /// The function to test the input elements. /// The input array. @@ -1039,8 +1041,6 @@ module Array = /// [1; 2] |> Array.forall isEven // evaluates to false /// /// - /// - /// This is an O(n) operation in the worst case, where n is the length of the array. [] val forall: predicate: ('T -> bool) -> array: 'T array -> bool @@ -1050,7 +1050,7 @@ module Array = /// two lengths of the collections. If any application returns false then the overall result is /// false and no further elements are tested. Otherwise, if one collection is longer /// than the other then the ArgumentException exception is raised. - /// Otherwise, true is returned. + /// Otherwise, true is returned. This is an O(n) operation in the worst case, where n is the length of the arrays. /// /// The function to test the input elements. /// The first input array. @@ -1090,8 +1090,6 @@ module Array = /// /// Throws ArgumentException. /// - /// - /// This is an O(n) operation in the worst case, where n is the length of the arrays. [] val forall2: predicate: ('T1 -> 'T2 -> bool) -> array1: 'T1 array -> array2: 'T2 array -> bool @@ -1265,7 +1263,7 @@ module Array = /// The input array. /// The input index. /// - /// Normally the syntax array[index] is preferred. + /// Normally the syntax array[index] is preferred. This is an O(1) operation. /// /// The value of the array at the given index. /// @@ -1289,8 +1287,6 @@ module Array = /// /// Throws IndexOutOfRangeException /// - /// - /// This is an O(1) operation. [] val get: array: 'T array -> index: int -> 'T @@ -1410,6 +1406,8 @@ module Array = /// /// Evaluates to [| 0; 0; 0; 0 |] /// + /// + /// This is an O(n) operation, where n is the count. [] val zeroCreate: count: int -> 'T array @@ -1588,7 +1586,7 @@ module Array = /// /// The value of the array at the given index. /// - /// Normally the syntax array[index] is preferred. + /// Normally the syntax array[index] is preferred. This is an O(1) operation. /// /// Thrown when the input array is null. /// Thrown when the index is negative or the input array does not contain enough elements. @@ -1610,8 +1608,6 @@ module Array = /// /// Throws ArgumentException /// - /// - /// This is an O(1) operation. [] val item: index: int -> array: 'T array -> 'T @@ -1621,7 +1617,7 @@ module Array = /// /// The length of the array. /// - /// The notation array.Length is preferred. + /// The notation array.Length is preferred. This is an O(1) operation. /// /// Thrown when the input array is null. /// @@ -1633,8 +1629,6 @@ module Array = /// /// Evaluates to 3 /// - /// - /// This is an O(1) operation. [] val length: array: 'T array -> int @@ -1868,7 +1862,7 @@ module Array = /// Returns the greatest of all elements of the array, compared via Operators.max on the function result. /// - /// Throws ArgumentException for empty arrays. + /// Throws ArgumentException for empty arrays. This is an O(n) operation, where n is the length of the array. /// /// The input array. /// @@ -1894,14 +1888,12 @@ module Array = /// /// Throws System.ArgumentException. /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val inline max: array: 'T array -> 'T when 'T: comparison /// Returns the greatest of all elements of the array, compared via Operators.max on the function result. /// - /// Throws ArgumentException for empty arrays. + /// Throws ArgumentException for empty arrays. This is an O(n) operation, where n is the length of the array. /// /// The function to transform the elements into a type supporting comparison. /// The input array. @@ -1928,14 +1920,12 @@ module Array = /// /// Throws System.ArgumentException. /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val inline maxBy: projection: ('T -> 'U) -> array: 'T array -> 'T when 'U: comparison /// Returns the lowest of all elements of the array, compared via Operators.min. /// - /// Throws ArgumentException for empty arrays + /// Throws ArgumentException for empty arrays This is an O(n) operation, where n is the length of the array. /// /// The input array. /// @@ -1961,14 +1951,12 @@ module Array = /// /// Throws System.ArgumentException. /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val inline min: array: 'T array -> 'T when 'T: comparison /// Returns the lowest of all elements of the array, compared via Operators.min on the function result. /// - /// Throws ArgumentException for empty arrays. + /// Throws ArgumentException for empty arrays. This is an O(n) operation, where n is the length of the array. /// /// The function to transform the elements into a type supporting comparison. /// The input array. @@ -1995,8 +1983,6 @@ module Array = /// /// Throws System.ArgumentException. /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val inline minBy: projection: ('T -> 'U) -> array: 'T array -> 'T when 'U: comparison @@ -2014,6 +2000,8 @@ module Array = /// /// Evaluates to [| 1; 2; 5 |]. /// + /// + /// This is an O(n) operation, where n is the length of the list. [] val ofList: list: 'T list -> 'T array @@ -2177,6 +2165,8 @@ module Array = /// /// Evaluates to [| "a"; "a"; "a" |]. /// + /// + /// This is an O(n) operation, where n is the count. [] val replicate: count: int -> initial: 'T -> 'T array @@ -2273,6 +2263,8 @@ module Array = /// /// Evaluates to [| 7 |]. /// + /// + /// This is an O(1) operation. [] val inline singleton: value: 'T -> 'T array @@ -2393,7 +2385,7 @@ module Array = /// /// input.[2..4] /// - /// + /// This is an O(count) operation. /// /// /// @@ -2403,15 +2395,13 @@ module Array = /// /// Evaluates to [| 2; 3; 4 |]. /// - /// - /// This is an O(count) operation. [] val sub: array: 'T array -> startIndex: int -> count: int -> 'T array /// Sorts the elements of an array, returning a new array. Elements are compared using . /// /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using . + /// For a stable sort, consider using . This is an O(n log n) operation, where n is the length of the array. /// /// The input array. /// @@ -2427,8 +2417,6 @@ module Array = /// /// Evaluates to [| 1; 1; 3; 4; 6; 8 |]. /// - /// - /// This is an O(n log n) operation, where n is the length of the array. [] val sort: array: 'T array -> 'T array when 'T: comparison @@ -2436,7 +2424,7 @@ module Array = /// Elements are compared using . /// /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using . + /// For a stable sort, consider using . This is an O(n log n) operation, where n is the length of the array. /// /// The function to transform array elements into the type that is compared. /// The input array. @@ -2453,15 +2441,13 @@ module Array = /// /// Evaluates to [|"a"; "dd"; "bbb"; "cccc"|]. /// - /// - /// This is an O(n log n) operation, where n is the length of the array. [] val sortBy: projection: ('T -> 'Key) -> array: 'T array -> 'T array when 'Key: comparison /// Sorts the elements of an array, using the given comparison function as the order, returning a new array. /// /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using . + /// For a stable sort, consider using . This is an O(n log n) operation, where n is the length of the array. /// /// The function to compare pairs of array elements. /// The input array. @@ -2483,8 +2469,6 @@ module Array = /// /// Evaluates to [|(0, "aa"); (2, "cc"); (3, "dd"); (1, "bbb")|]. /// - /// - /// This is an O(n log n) operation, where n is the length of the array. [] val sortWith: comparer: ('T -> 'T -> int) -> array: 'T array -> 'T array @@ -2492,7 +2476,7 @@ module Array = /// Elements are compared using . /// /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using . + /// For a stable sort, consider using . This is an O(n log n) operation, modifying the array in place. /// /// The function to transform array elements into the type that is compared. /// The input array. @@ -2507,8 +2491,6 @@ module Array = /// /// After evaluation array contains [|"a"; "dd"; "bbb"; "cccc"|]. /// - /// - /// This is an O(n log n) operation, modifying the array in place. [] val sortInPlaceBy: projection: ('T -> 'Key) -> array: 'T array -> unit when 'Key: comparison @@ -2552,6 +2534,8 @@ module Array = /// /// After evaluation array contains [| 1; 1; 3; 4; 6; 8 |]. /// + /// + /// This is an O(n log n) operation, modifying the array in place. [] val sortInPlace: array: 'T array -> unit when 'T: comparison @@ -2582,7 +2566,7 @@ module Array = /// Sorts the elements of an array, in descending order, returning a new array. Elements are compared using . /// /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using . + /// For a stable sort, consider using . This is an O(n log n) operation, where n is the length of the array. /// /// The input array. /// @@ -2596,8 +2580,6 @@ module Array = /// /// Evaluates to [| 8; 6; 4; 3; 1; 1 |]. /// - /// - /// This is an O(n log n) operation, where n is the length of the array. [] val inline sortDescending: array: 'T array -> 'T array when 'T: comparison @@ -2605,7 +2587,7 @@ module Array = /// Elements are compared using . /// /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using . + /// For a stable sort, consider using . This is an O(n log n) operation, where n is the length of the array. /// /// The function to transform array elements into the type that is compared. /// The input array. @@ -2620,8 +2602,6 @@ module Array = /// /// Evaluates to [|"cccc"; "bbb"; "dd"; "a"|]. /// - /// - /// This is an O(n log n) operation, where n is the length of the array. [] val inline sortByDescending: projection: ('T -> 'Key) -> array: 'T array -> 'T array when 'Key: comparison @@ -2641,6 +2621,8 @@ module Array = /// /// Evaluates to 11. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline sum: array: ^T array -> ^T when ^T: (static member (+): ^T * ^T -> ^T) and ^T: (static member Zero: ^T) @@ -2671,7 +2653,7 @@ module Array = /// Returns the first N elements of the array. /// Throws InvalidOperationException /// if the count exceeds the number of elements in the array. Array.truncate - /// returns as many items as the array contains instead of throwing an exception. + /// returns as many items as the array contains instead of throwing an exception. This is an O(count) operation. /// /// The number of items to take. /// The input array. @@ -2709,8 +2691,6 @@ module Array = /// /// Evaluates to [| |]. /// - /// - /// This is an O(count) operation. [] val take: count: int -> array: 'T array -> 'T array @@ -2777,6 +2757,8 @@ module Array = /// /// Evaluates to [ 1; 2; 5 ]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val toList: array: 'T array -> 'T list @@ -3041,6 +3023,8 @@ module Array = /// /// Evaluates to [| 1; 2; 4; 8; 16; 32; 64 |] /// + /// + /// This is an O(n) operation, where n is the number of elements generated. [] val unfold<'T, 'State> : generator: ('State -> ('T * 'State) option) -> state: 'State -> 'T array @@ -3081,6 +3065,8 @@ module Array = /// /// Evaluates numbers to [|1; 2|], names to [|"one"; "two"|] and roman to [|"I"; "II"|]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val unzip3: array: ('T1 * 'T2 * 'T3) array -> ('T1 array * 'T2 array * 'T3 array) @@ -3094,7 +3080,7 @@ module Array = /// /// Thrown when the input array is null. /// - /// This is identical to Array.filter. + /// This is identical to Array.filter. This is an O(n) operation, where n is the length of the array. /// /// Select only the even numbers: /// @@ -3104,8 +3090,6 @@ module Array = /// /// Evaluates to [| 2; 4 |] /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val where: predicate: ('T -> bool) -> array: 'T array -> 'T array @@ -3315,6 +3299,8 @@ module Array = /// /// Can evaluate to [| 0; 2; 4; 3; 1 |]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val randomShuffle: source: 'T array -> 'T array @@ -3336,6 +3322,8 @@ module Array = /// /// Can evaluate to [| 0; 2; 4; 3; 1 |]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val randomShuffleWith: random: Random -> source: 'T array -> 'T array @@ -3357,6 +3345,8 @@ module Array = /// /// Can evaluate to [| 0; 2; 4; 3; 1 |]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val randomShuffleBy: randomizer: (unit -> float) -> source: 'T array -> 'T array @@ -3374,6 +3364,8 @@ module Array = /// /// After evaluation array can contain [| 0; 2; 4; 3; 1 |]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val randomShuffleInPlace: source: 'T array -> unit @@ -3392,6 +3384,8 @@ module Array = /// /// After evaluation array can contain [| 0; 2; 4; 3; 1 |]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val randomShuffleInPlaceWith: random: Random -> source: 'T array -> unit @@ -3411,6 +3405,8 @@ module Array = /// /// After evaluation array can contain [| 0; 2; 4; 3; 1 |]. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val randomShuffleInPlaceBy: randomizer: (unit -> float) -> source: 'T array -> unit @@ -3431,6 +3427,8 @@ module Array = /// /// Can evaluate to 3. /// + /// + /// This is an O(1) operation. [] val randomChoice: source: 'T array -> 'T @@ -3453,6 +3451,8 @@ module Array = /// /// Can evaluate to 3. /// + /// + /// This is an O(1) operation. [] val randomChoiceWith: random: Random -> source: 'T array -> 'T @@ -3475,6 +3475,8 @@ module Array = /// /// Can evaluate to 3. /// + /// + /// This is an O(1) operation. [] val randomChoiceBy: randomizer: (unit -> float) -> source: 'T array -> 'T @@ -3497,6 +3499,8 @@ module Array = /// /// Can evaluate to [| 3; 1; 3 |]. /// + /// + /// This is an O(count) operation. [] val randomChoices: count: int -> source: 'T array -> 'T array @@ -3521,6 +3525,8 @@ module Array = /// /// Can evaluate to [| 3; 1; 3 |]. /// + /// + /// This is an O(count) operation. [] val randomChoicesWith: random: Random -> count: int -> source: 'T array -> 'T array @@ -3545,6 +3551,8 @@ module Array = /// /// Can evaluate to [| 3; 1; 3 |]. /// + /// + /// This is an O(count) operation. [] val randomChoicesBy: randomizer: (unit -> float) -> count: int -> source: 'T array -> 'T array @@ -3568,6 +3576,8 @@ module Array = /// /// Can evaluate to [| 3; 1; 2 |]. /// + /// + /// This is an O(count) operation. [] val randomSample: count: int -> source: 'T array -> 'T array @@ -3593,6 +3603,8 @@ module Array = /// /// Can evaluate to [| 3; 1; 2 |]. /// + /// + /// This is an O(count) operation. [] val randomSampleWith: random: Random -> count: int -> source: 'T array -> 'T array @@ -3618,6 +3630,8 @@ module Array = /// /// Can evaluate to [| 3; 1; 2 |]. /// + /// + /// This is an O(count) operation. [] val randomSampleBy: randomizer: (unit -> float) -> count: int -> source: 'T array -> 'T array @@ -3628,7 +3642,7 @@ module Array = /// /// The predicate is applied to the elements of the input collection in parallel. If any application /// returns false then the overall result is false and testing of other elements in all threads is stopped at system's earliest convenience. - /// Otherwise, true is returned. + /// Otherwise, true is returned. This is an O(n) operation in the worst case, where n is the length of the array. /// /// The function to test the input elements. /// The input array. @@ -3646,8 +3660,6 @@ module Array = /// [1; 2] |> Array.Parallel.forall isEven // evaluates to false /// /// - /// - /// This is an O(n) operation in the worst case, where n is the length of the array. [] val forall: predicate: ('T -> bool) -> array: 'T array -> bool @@ -3655,7 +3667,7 @@ module Array = /// /// The predicate is applied to the elements of the input array in parallel. If any application /// returns true then the overall result is true and testing of other elements in all threads is stopped at system's earliest convenience. - /// Otherwise, false is returned. + /// Otherwise, false is returned. This is an O(n) operation in the worst case, where n is the length of the array. /// /// The function to test the input elements. /// The input array. @@ -3681,8 +3693,6 @@ module Array = /// /// Evaluates to false /// - /// - /// This is an O(n) operation in the worst case, where n is the length of the array. [] val exists: predicate: ('T -> bool) -> array: 'T array -> bool @@ -3789,7 +3799,7 @@ module Array = /// Raises ArgumentException if the array is empty. /// The order of processing is not guaranteed. For that reason, the 'reduce' function argument should be commutative. /// (That is, changing the order of execution must not affect the result) - /// Also, compared to the non-parallel version of Array.reduce, the 'reduce' function may be invoked more times due to the resulting reduction from participating threads. + /// Also, compared to the non-parallel version of Array.reduce, the 'reduce' function may be invoked more times due to the resulting reduction from participating threads. This is an O(n) operation, where n is the length of the array. /// /// The function to reduce a pair of elements to a single element. /// The input array. @@ -3808,8 +3818,6 @@ module Array = /// Evaluates to 1 + 3 + 4 + 2. However, the system could have decided to compute (1+3) and (4+2) first, and then put them together. /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val inline reduce: reduction: ('T -> 'T -> 'T) -> array: 'T array -> 'T @@ -3817,7 +3825,7 @@ module Array = /// After processing entire input, results from all threads are reduced together. /// Raises ArgumentException if the array is empty. /// The order of processing is not guaranteed. For that reason, the 'reduction' function argument should be commutative. - /// (That is, changing the order of execution must not affect the result) + /// (That is, changing the order of execution must not affect the result) This is an O(n) operation, where n is the length of the array. /// /// The function to project from elements of the input array /// The function to reduce a pair of projected elements to a single element. @@ -3836,13 +3844,12 @@ module Array = /// /// Evaluates to 1 + 3 + 4 + 2. However, the system could have decided to compute (1+3) and (4+2) first, and then put them together. /// - [] val reduceBy: projection: ('T -> 'U) -> reduction: ('U -> 'U -> 'U) -> array: 'T array -> 'U /// Returns the greatest of all elements of the array, compared via Operators.max. /// - /// Throws ArgumentException for empty arrays. + /// Throws ArgumentException for empty arrays. This is an O(n) operation, where n is the length of the array. /// /// The input array. /// @@ -3868,14 +3875,12 @@ module Array = /// /// Throws System.ArgumentException. /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val inline max: array: 'T array -> 'T when 'T: comparison /// Returns the greatest of all elements of the array, compared via Operators.max on the function result. /// - /// Throws ArgumentException for empty arrays. + /// Throws ArgumentException for empty arrays. This is an O(n) operation, where n is the length of the array. /// /// The function to transform the elements into a type supporting comparison. /// The input array. @@ -3902,14 +3907,12 @@ module Array = /// /// Throws System.ArgumentException. /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val inline maxBy: projection: ('T -> 'U) -> array: 'T array -> 'T when 'U: comparison /// Returns the smallest of all elements of the array, compared via Operators.min. /// - /// Throws ArgumentException for empty arrays + /// Throws ArgumentException for empty arrays This is an O(n) operation, where n is the length of the array. /// /// The input array. /// @@ -3935,14 +3938,12 @@ module Array = /// /// Throws System.ArgumentException. /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val inline min: array: 'T array -> 'T when 'T: comparison /// Returns the lowest of all elements of the array, compared via Operators.min on the function result. /// - /// Throws ArgumentException for empty arrays. + /// Throws ArgumentException for empty arrays. This is an O(n) operation, where n is the length of the array. /// /// The function to transform the elements into a type supporting comparison. /// The input array. @@ -3969,8 +3970,6 @@ module Array = /// /// Throws System.ArgumentException. /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val inline minBy: projection: ('T -> 'U) -> array: 'T array -> 'T when 'U: comparison @@ -3990,6 +3989,8 @@ module Array = /// /// Evaluates to 11. /// + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline sum: array: ^T array -> ^T when ^T: (static member (+): ^T * ^T -> ^T) and ^T: (static member Zero: ^T) @@ -4091,7 +4092,7 @@ module Array = /// the function returns Some(x). /// /// Performs the operation in parallel using . - /// The order in which the given function is applied to elements of the input array is not specified. + /// The order in which the given function is applied to elements of the input array is not specified. This is an O(n) operation, where n is the length of the array. /// /// The function to generate options from the elements. /// The input array. @@ -4117,15 +4118,13 @@ module Array = /// /// Evaluates to [| 2 |] /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val choose: chooser: ('T -> 'U option) -> array: 'T array -> 'U array /// For each element of the array, apply the given function. Concatenate all the results and return the combined array. /// /// Performs the operation in parallel using . - /// The order in which the given function is applied to elements of the input array is not specified. + /// The order in which the given function is applied to elements of the input array is not specified. This is an O(n) operation, where n is the total output length. /// /// /// The input array. @@ -4153,8 +4152,6 @@ module Array = /// /// Evaluates to [| 1; 2; 3; 4 |] /// - /// - /// This is an O(n) operation, where n is the total output length. [] val collect: mapping: ('T -> 'U array) -> array: 'T array -> 'U array @@ -4162,7 +4159,7 @@ module Array = /// to each of the elements of the array. /// /// Performs the operation in parallel using . - /// The order in which the given function is applied to elements of the input array is not specified. + /// The order in which the given function is applied to elements of the input array is not specified. This is an O(n) operation, where n is the length of the array. /// /// /// The input array. @@ -4179,8 +4176,6 @@ module Array = /// /// Evaluates to [| 1; 3; 2 |] /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val map: mapping: ('T -> 'U) -> array: 'T array -> 'U array @@ -4189,7 +4184,7 @@ module Array = /// function indicates the index of element being transformed. /// /// Performs the operation in parallel using . - /// The order in which the given function is applied to elements of the input array is not specified. + /// The order in which the given function is applied to elements of the input array is not specified. This is an O(n) operation, where n is the length of the array. /// /// /// The input array. @@ -4206,8 +4201,6 @@ module Array = /// /// Evaluates to [| 10; 11; 12 |] /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val mapi: mapping: (int -> 'T -> 'U) -> array: 'T array -> 'U array @@ -4217,7 +4210,7 @@ module Array = /// /// Performs the operation in parallel using . /// The order in which the given function is applied to elements of the input array is not specified. - /// The order of the keys and values in the result is also not specified + /// The order of the keys and values in the result is also not specified This is an O(n) operation, where n is the length of the array. /// A function that transforms an element of the array into a comparable key. /// The input array. /// @@ -4234,15 +4227,13 @@ module Array = /// Evaluates to [| (1, [| 1; 3; 5 |]); (0, [| 2; 4 |]) |] /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val groupBy: projection: ('T -> 'Key) -> array: 'T array -> ('Key * 'T array) array when 'Key: equality /// Apply the given function to each element of the array. /// /// Performs the operation in parallel using . - /// The order in which the given function is applied to elements of the input array is not specified. + /// The order in which the given function is applied to elements of the input array is not specified. This is an O(n) operation, where n is the length of the array. /// /// /// The input array. @@ -4262,8 +4253,6 @@ module Array = /// b /// /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val iter: action: ('T -> unit) -> array: 'T array -> unit @@ -4271,7 +4260,7 @@ module Array = /// function indicates the index of element. /// /// Performs the operation in parallel using . - /// The order in which the given function is applied to elements of the input array is not specified. + /// The order in which the given function is applied to elements of the input array is not specified. This is an O(n) operation, where n is the length of the array. /// /// /// The input array. @@ -4291,15 +4280,13 @@ module Array = /// 1: b /// /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val iteri: action: (int -> 'T -> unit) -> array: 'T array -> unit /// Create an array given the dimension and a generator function to compute the elements. /// /// Performs the operation in parallel using . - /// The order in which the given function is applied to indices is not specified. + /// The order in which the given function is applied to indices is not specified. This is an O(n) operation, where n is the count. /// /// /// @@ -4320,7 +4307,7 @@ module Array = /// respectively /// /// Performs the operation in parallel using . - /// The order in which the given function is applied to indices is not specified. + /// The order in which the given function is applied to indices is not specified. This is an O(n) operation, where n is the length of the array. /// /// The function to test the input elements. /// The input array. @@ -4337,15 +4324,13 @@ module Array = /// /// Evaluates to ([|2; 4|], [|1; 3|]). /// - /// - /// This is an O(n) operation, where n is the length of the array. [] val partition: predicate: ('T -> bool) -> array: 'T array -> 'T array * 'T array /// Sorts the elements of an array in parallel, returning a new array. Elements are compared using . /// /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using . + /// For a stable sort, consider using . This is an O(n log n) operation, where n is the length of the array. /// /// The input array. /// @@ -4361,8 +4346,6 @@ module Array = /// /// Evaluates to [| 1; 1 3; 4; 6; 8 |]. /// - /// - /// This is an O(n log n) operation, where n is the length of the array. [] val sort: array: 'T array -> 'T array when 'T: comparison @@ -4370,7 +4353,7 @@ module Array = /// Elements are compared using . /// /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using . + /// For a stable sort, consider using . This is an O(n log n) operation, where n is the length of the array. /// /// The function to transform array elements into the type that is compared. /// The input array. @@ -4388,15 +4371,13 @@ module Array = /// Evaluates to [|"a"; "dd"; "bbb"; "cccc"|]. /// - /// - /// This is an O(n log n) operation, where n is the length of the array. [] val sortBy: projection: ('T -> 'Key) -> array: 'T array -> 'T array when 'Key: comparison /// Sorts the elements of an array in parallel, using the given comparison function as the order, returning a new array. /// /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using . + /// For a stable sort, consider using . This is an O(n log n) operation, where n is the length of the array. /// /// The function to compare pairs of array elements. /// The input array. @@ -4418,8 +4399,6 @@ module Array = /// /// Evaluates to [|(0, "aa"); (2, "cc"); (3, "dd"); (1, "bbb")|]. /// - /// - /// This is an O(n log n) operation, where n is the length of the array. [] val sortWith: comparer: ('T -> 'T -> int) -> array: 'T array -> 'T array @@ -4427,7 +4406,7 @@ module Array = /// Elements are compared using . /// /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using . + /// For a stable sort, consider using . This is an O(n log n) operation, modifying the array in place. /// /// The function to transform array elements into the type that is compared. /// The input array. @@ -4442,8 +4421,6 @@ module Array = /// /// After evaluation array contains [|"a"; "dd"; "bbb"; "cccc"|]. /// - /// - /// This is an O(n log n) operation, modifying the array in place. [] val sortInPlaceBy: projection: ('T -> 'Key) -> array: 'T array -> unit when 'Key: comparison @@ -4487,13 +4464,15 @@ module Array = /// /// After evaluation array contains [| 1; 1; 3; 4; 6; 8 |]. /// + /// + /// This is an O(n log n) operation, modifying the array in place. [] val sortInPlace: array: 'T array -> unit when 'T: comparison /// Sorts the elements of an array in parallel, in descending order, returning a new array. Elements are compared using . /// /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using . + /// For a stable sort, consider using . This is an O(n log n) operation, where n is the length of the array. /// /// The input array. /// @@ -4507,8 +4486,6 @@ module Array = /// /// Evaluates to [| 8; 6; 4; 3; 1; 1 |]. /// - /// - /// This is an O(n log n) operation, where n is the length of the array. [] val sortDescending: array: 'T array -> 'T array when 'T: comparison @@ -4516,7 +4493,7 @@ module Array = /// Elements are compared using . /// /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using . + /// For a stable sort, consider using . This is an O(n log n) operation, where n is the length of the array. /// /// The function to transform array elements into the type that is compared. /// The input array. @@ -4531,8 +4508,6 @@ module Array = /// /// Evaluates to [|"cccc"; "bbb"; "dd"; "a"|]. /// - /// - /// This is an O(n log n) operation, where n is the length of the array. [] val sortByDescending: projection: ('T -> 'Key) -> array: 'T array -> 'T array when 'Key: comparison From 46a3ceea39565acf28c3467268d8d7860ce77c8b Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jan 2026 19:54:55 +0100 Subject: [PATCH 08/17] Add complexity remarks to Seq random* functions Added O(n) complexity documentation to 12 random* functions in seq.fsi: - randomShuffle, randomShuffleWith, randomShuffleBy - randomChoice, randomChoiceWith, randomChoiceBy - randomChoices, randomChoicesWith, randomChoicesBy - randomSample, randomSampleWith, randomSampleBy All functions have O(n) complexity because they first materialize the sequence to an array before performing random operations. Build: 0 errors XmlDocumentationValidation: 1 passed, 0 failed --- src/FSharp.Core/seq.fsi | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/FSharp.Core/seq.fsi b/src/FSharp.Core/seq.fsi index 67798d9aadf..cdf282750e8 100644 --- a/src/FSharp.Core/seq.fsi +++ b/src/FSharp.Core/seq.fsi @@ -3137,6 +3137,8 @@ module Seq = /// /// Can evaluate to seq { 0; 2; 4; 3; 1 }. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val randomShuffle: source: seq<'T> -> seq<'T> @@ -3158,6 +3160,8 @@ module Seq = /// /// Can evaluate to seq { 0; 2; 4; 3; 1 }. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val randomShuffleWith: random: Random -> source: seq<'T> -> seq<'T> @@ -3178,6 +3182,8 @@ module Seq = /// /// Can evaluate to seq { 0; 2; 4; 3; 1 }. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val randomShuffleBy: randomizer: (unit -> float) -> source: seq<'T> -> seq<'T> @@ -3200,6 +3206,8 @@ module Seq = /// /// Can evaluate to 3. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val randomChoice: source: seq<'T> -> 'T @@ -3224,6 +3232,8 @@ module Seq = /// /// Can evaluate to 3. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val randomChoiceWith: random: Random -> source: seq<'T> -> 'T @@ -3249,6 +3259,8 @@ module Seq = /// /// Can evaluate to 3. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val randomChoiceBy: randomizer: (unit -> float) -> source: seq<'T> -> 'T @@ -3273,6 +3285,8 @@ module Seq = /// /// Can evaluate to seq { 3; 1; 3 }. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val randomChoices: count: int -> source: seq<'T> -> seq<'T> @@ -3299,6 +3313,8 @@ module Seq = /// /// Can evaluate to seq { 3; 1; 3 }. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val randomChoicesWith: random: Random -> count: int -> source: seq<'T> -> seq<'T> @@ -3325,6 +3341,8 @@ module Seq = /// /// Can evaluate to seq { 3; 1; 3 }. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val randomChoicesBy: randomizer: (unit -> float) -> count: int -> source: seq<'T> -> seq<'T> @@ -3350,6 +3368,8 @@ module Seq = /// /// Can evaluate to seq { 3; 1; 2 }. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val randomSample: count: int -> source: seq<'T> -> seq<'T> @@ -3377,6 +3397,8 @@ module Seq = /// /// Can evaluate to seq { 3; 1; 2 }. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val randomSampleWith: random: Random -> count: int -> source: seq<'T> -> seq<'T> @@ -3404,5 +3426,7 @@ module Seq = /// /// Can evaluate to seq { 3; 1; 2 }. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val randomSampleBy: randomizer: (unit -> float) -> count: int -> source: seq<'T> -> seq<'T> From c5b36f1ad85d0bd483d307a568eaf88124670314 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jan 2026 20:24:05 +0100 Subject: [PATCH 09/17] Fix duplicate remarks tags in Seq module documentation Merged 41 duplicate tags where complexity remarks were added separately from existing behavioral remarks. Each function now has at most one section containing both behavioral documentation and complexity information. - Build: 0 errors - XmlDocumentationValidation test: 1 passed - 107 remarks covering 118 val declarations - No duplicate remarks tags per function - Format correctly distinguishes lazy construction vs enumeration cost --- src/FSharp.Core/seq.fsi | 168 ++++++++++------------------------------ 1 file changed, 43 insertions(+), 125 deletions(-) diff --git a/src/FSharp.Core/seq.fsi b/src/FSharp.Core/seq.fsi index cdf282750e8..80e7fd16ba9 100644 --- a/src/FSharp.Core/seq.fsi +++ b/src/FSharp.Core/seq.fsi @@ -40,7 +40,7 @@ module Seq = /// /// The returned sequence may be passed between threads safely. However, /// individual IEnumerator values generated from the returned sequence should not be accessed - /// concurrently. + /// concurrently. Sequence construction is O(1). Enumeration is O(n+m), where n and m are the lengths of the sequences. /// /// The first sequence. /// The second sequence. @@ -56,15 +56,13 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 1; 2; 3; 4 } /// - /// - /// Sequence construction is O(1). Enumeration is O(n+m), where n and m are the lengths of the sequences. [] val append: source1: seq<'T> -> source2: seq<'T> -> seq<'T> /// Returns the average of the elements in the sequence. /// /// The elements are averaged using the + operator, DivideByInt method and Zero property - /// associated with the element type. + /// associated with the element type. This is an O(n) operation, where n is the length of the sequence. /// /// The input sequence. /// @@ -86,8 +84,6 @@ module Seq = /// /// Throws ArgumentException /// - /// - /// This is an O(n) operation, where n is the length of the sequence. [] val inline average: source: seq< ^T > -> ^T @@ -99,7 +95,7 @@ module Seq = /// of the sequence. /// /// The elements are averaged using the + operator, DivideByInt method and Zero property - /// associated with the generated type. + /// associated with the generated type. This is an O(n) operation, where n is the length of the sequence. /// /// A function applied to transform each element of the sequence. /// The input sequence. @@ -128,8 +124,6 @@ module Seq = /// /// Throws ArgumentException /// - /// - /// This is an O(n) operation, where n is the length of the sequence. [] val inline averageBy: projection: ('T -> ^U) -> source: seq<'T> -> ^U @@ -159,7 +153,9 @@ module Seq = /// The enumerator may be disposed and underlying cache storage released by /// converting the returned sequence object to type IDisposable, and calling the Dispose method /// on this object. The sequence object may then be re-enumerated and a fresh enumerator will - /// be used. + /// be used. + /// + /// Caching requires O(k) space for k accessed elements. /// /// The input sequence. /// @@ -177,8 +173,6 @@ module Seq = /// Evaluates to a sequence yielding the same results as seq { 1; 2; 3 }, /// and it will not do the calculation again when called. /// - /// - /// Caching requires O(k) space for k accessed elements. [] val cache: source: seq<'T> -> seq<'T> @@ -187,7 +181,7 @@ module Seq = /// The use of this function usually requires a type annotation. /// An incorrect type annotation may result in runtime type /// errors. - /// Individual IEnumerator values generated from the returned sequence should not be accessed concurrently. + /// Individual IEnumerator values generated from the returned sequence should not be accessed concurrently. Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. /// /// The input sequence. /// @@ -201,8 +195,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 1; 2; 3 }, explicitly typed as seq<int>. /// - /// - /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val cast: source: IEnumerable -> seq<'T> @@ -212,7 +204,7 @@ module Seq = /// /// The returned sequence may be passed between threads safely. However, /// individual IEnumerator values generated from the returned sequence should not - /// be accessed concurrently. + /// be accessed concurrently. Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. /// /// A function to transform items of type T into options of type U. /// The input sequence of type T. @@ -234,8 +226,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 2 } /// - /// - /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val choose: chooser: ('T -> 'U option) -> source: seq<'T> -> seq<'U> @@ -270,7 +260,7 @@ module Seq = /// Applies the given function to each element of the sequence and concatenates all the /// results. /// - /// Remember sequence is lazy, effects are delayed until it is enumerated. + /// Remember sequence is lazy, effects are delayed until it is enumerated. Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. /// /// A function to transform elements of the input sequence into the sequences /// that will then be concatenated. @@ -299,8 +289,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 1; 2; 3; 4 } /// - /// - /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val collect: mapping: ('T -> 'Collection) -> source: seq<'T> -> seq<'U> when 'Collection :> seq<'U> @@ -391,7 +379,7 @@ module Seq = /// enumeration. /// /// The returned sequence may be passed between threads safely. However, - /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. + /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. Sequence construction is O(1). Enumeration is O(n), where n is the total number of elements. /// /// The input enumeration-of-enumerations. /// @@ -407,8 +395,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 1; 2; 3; 4; 5 } /// - /// - /// Sequence construction is O(1). Enumeration is O(n), where n is the total number of elements. [] val concat: sources: seq<'Collection> -> seq<'T> when 'Collection :> seq<'T> @@ -436,7 +422,7 @@ module Seq = /// Note that this function returns a sequence that digests the whole initial sequence as soon as /// that sequence is iterated. As a result this function should not be used with /// large or infinite sequences. The function makes no assumption on the ordering of the original - /// sequence. + /// sequence. This is an O(n) operation, where n is the length of the sequence. /// /// A function transforming each item of the input sequence into a key to be /// compared against the others. @@ -456,8 +442,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { ("a", 2); ("b", 1) } /// - /// - /// This is an O(n) operation, where n is the length of the sequence. [] val countBy: projection: ('T -> 'Key) -> source: seq<'T> -> seq<'Key * int> when 'Key: equality @@ -528,7 +512,7 @@ module Seq = /// Splits the input sequence into at most count chunks. /// /// This function returns a sequence that digests the whole initial sequence as soon as that - /// sequence is iterated. As a result this function should not be used with large or infinite sequences. + /// sequence is iterated. As a result this function should not be used with large or infinite sequences. This function consumes the whole input sequence before yielding the first element of the result sequence. This is an O(n) operation, where n is the length of the sequence. /// /// The maximum number of chunks. /// The input sequence. @@ -538,8 +522,6 @@ module Seq = /// Thrown when the input sequence is null. /// Thrown when count is not positive. /// - /// This function consumes the whole input sequence before yielding the first element of the result sequence. - /// /// /// /// let inputs = [1; 2; 3; 4; 5] @@ -557,8 +539,6 @@ module Seq = /// /// Throws ArgumentException /// - /// - /// This is an O(n) operation, where n is the length of the sequence. [] val splitInto: count: int -> source: seq<'T> -> seq<'T array> @@ -581,7 +561,7 @@ module Seq = /// Note that this function returns a sequence that digests the whole of the first input sequence as soon as /// the result sequence is iterated. As a result this function should not be used with /// large or infinite sequences in the first parameter. The function makes no assumption on the ordering of the first input - /// sequence. + /// sequence. This is an O(n+m) operation using hash-based exclusion. /// /// A sequence whose elements that also occur in the second sequence will cause those elements to be /// removed from the returned sequence. @@ -600,8 +580,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 2; 4 } /// - /// - /// This is an O(n+m) operation using hash-based exclusion. [] val except: itemsToExclude: seq<'T> -> source: seq<'T> -> seq<'T> when 'T: equality @@ -609,7 +587,7 @@ module Seq = /// /// The predicate is applied to the elements of the input sequence. If any application /// returns true then the overall result is true and no further elements are tested. - /// Otherwise, false is returned. + /// Otherwise, false is returned. This is an O(n) operation in the worst case, where n is the length of the sequence. /// /// A function to test each item of the input sequence. /// The input sequence. @@ -635,8 +613,6 @@ module Seq = /// /// Evaluates to false /// - /// - /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val exists: predicate: ('T -> bool) -> source: seq<'T> -> bool @@ -645,7 +621,7 @@ module Seq = /// The predicate is applied to matching elements in the two sequences up to the lesser of the /// two lengths of the collections. If any application returns true then the overall result is /// true and no further elements are tested. Otherwise, false is returned. If one sequence is shorter than - /// the other then the remaining elements of the longer sequence are ignored. + /// the other then the remaining elements of the longer sequence are ignored. This is an O(n) operation in the worst case, where n is the length of the sequences. /// /// A function to test each pair of items from the input sequences. /// The first input sequence. @@ -674,8 +650,6 @@ module Seq = /// /// Evaluates to true /// - /// - /// This is an O(n) operation in the worst case, where n is the length of the sequences. [] val exists2: predicate: ('T1 -> 'T2 -> bool) -> source1: seq<'T1> -> source2: seq<'T2> -> bool @@ -685,7 +659,7 @@ module Seq = /// The returned sequence may be passed between threads safely. However, /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. /// - /// Remember sequence is lazy, effects are delayed until it is enumerated. + /// Remember sequence is lazy, effects are delayed until it is enumerated. Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. /// /// A function to test whether each item in the input sequence should be included in the output. /// The input sequence. @@ -702,8 +676,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 2; 4 } /// - /// - /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val filter: predicate: ('T -> bool) -> source: seq<'T> -> seq<'T> @@ -715,7 +687,7 @@ module Seq = /// /// Remember sequence is lazy, effects are delayed until it is enumerated. /// - /// A synonym for Seq.filter. + /// A synonym for Seq.filter. Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. /// /// A function to test whether each item in the input sequence should be included in the output. /// The input sequence. @@ -730,8 +702,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 2; 4 } /// - /// - /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val where: predicate: ('T -> bool) -> source: seq<'T> -> seq<'T> @@ -771,7 +741,7 @@ module Seq = /// Returns the last element for which the given function returns True. /// /// This function digests the whole initial sequence as soon as it is called. As a - /// result this function should not be used with large or infinite sequences. + /// result this function should not be used with large or infinite sequences. This is an O(n) operation in the worst case, where n is the length of the sequence. /// /// A function to test whether an item in the sequence should be returned. /// The input sequence. @@ -799,8 +769,6 @@ module Seq = /// /// Throws KeyNotFoundException /// - /// - /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val findBack: predicate: ('T -> bool) -> source: seq<'T> -> 'T @@ -839,7 +807,7 @@ module Seq = /// Returns the index of the last element for which the given function returns True. /// /// This function digests the whole initial sequence as soon as it is called. As a - /// result this function should not be used with large or infinite sequences. + /// result this function should not be used with large or infinite sequences. This is an O(n) operation in the worst case, where n is the length of the sequence. /// /// A function to test whether the index of a particular element should be returned. /// The input sequence. @@ -867,8 +835,6 @@ module Seq = /// /// Throws KeyNotFoundException /// - /// - /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val findIndexBack: predicate: ('T -> bool) -> source: seq<'T> -> int @@ -910,7 +876,7 @@ module Seq = /// The two sequences need not have equal lengths: /// when one sequence is exhausted any remaining elements in the other sequence are ignored. /// If the input function is f and the elements are i0...iN and j0...jN - /// then computes f (... (f s i0 j0)...) iN jN. + /// then computes f (... (f s i0 j0)...) iN jN. This is an O(n) operation, where n is the length of the sequences. /// /// The function to update the state given the input elements. /// The initial state. @@ -936,8 +902,6 @@ module Seq = /// /// Evaluates to 1 /// - /// - /// This is an O(n) operation, where n is the length of the sequences. [] val fold2<'T1, 'T2, 'State> : folder: ('State -> 'T1 -> 'T2 -> 'State) -> state: 'State -> source1: seq<'T1> -> source2: seq<'T2> -> 'State @@ -954,7 +918,7 @@ module Seq = /// /// Thrown when the input sequence is null. /// - /// This function consumes the whole input sequence before returning the result. + /// This function consumes the whole input sequence before returning the result. This is an O(n) operation, where n is the length of the sequence. /// /// /// @@ -984,8 +948,6 @@ module Seq = /// Text = " 3 -2 -1 0 1" } /// /// - /// - /// This is an O(n) operation, where n is the length of the sequence. [] val foldBack<'T, 'State> : folder: ('T -> 'State -> 'State) -> source: seq<'T> -> state: 'State -> 'State @@ -1005,7 +967,7 @@ module Seq = /// /// /// This function consumes the whole of both inputs sequences before returning the result. As a - /// result this function should not be used with large or infinite sequences. + /// result this function should not be used with large or infinite sequences. This is an O(n) operation, where n is the length of the sequences. /// /// /// @@ -1038,8 +1000,6 @@ module Seq = /// Text = " (-3,1) (-2,2) (-1,3)" } /// /// - /// - /// This is an O(n) operation, where n is the length of the sequences. [] val foldBack2<'T1, 'T2, 'State> : folder: ('T1 -> 'T2 -> 'State -> 'State) -> source1: seq<'T1> -> source2: seq<'T2> -> state: 'State -> 'State @@ -1048,7 +1008,7 @@ module Seq = /// /// The predicate is applied to the elements of the input sequence. If any application /// returns false then the overall result is false and no further elements are tested. - /// Otherwise, true is returned. + /// Otherwise, true is returned. This is an O(n) operation in the worst case, where n is the length of the sequence. /// /// A function to test an element of the input sequence. /// The input sequence. @@ -1066,8 +1026,6 @@ module Seq = /// [1; 2] |> Seq.forall isEven // evaluates to false /// /// - /// - /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val forall: predicate: ('T -> bool) -> source: seq<'T> -> bool @@ -1114,7 +1072,7 @@ module Seq = /// This function returns a sequence that digests the whole initial sequence as soon as /// that sequence is iterated. As a result this function should not be used with /// large or infinite sequences. The function makes no assumption on the ordering of the original - /// sequence. + /// sequence. This is an O(n) operation, where n is the length of the sequence. /// /// A function that transforms an element of the sequence into a comparable key. /// The input sequence. @@ -1129,8 +1087,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { (1, seq { 1; 3; 5 }); (0, seq { 2; 4 }) } /// - /// - /// This is an O(n) operation, where n is the length of the sequence. [] val groupBy: projection: ('T -> 'Key) -> source: seq<'T> -> seq<'Key * seq<'T>> when 'Key: equality @@ -1368,7 +1324,7 @@ module Seq = /// generated. /// /// The returned sequence may be passed between threads safely. However, - /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. + /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. This is an O(n) operation, where n is the count. /// /// The maximum number of items to generate for the sequence. /// A function that generates an item in the sequence from a given index. @@ -1390,8 +1346,6 @@ module Seq = /// /// Throws ArgumentException /// - /// - /// This is an O(n) operation, where n is the count. [] val init: count: int -> initializer: (int -> 'T) -> seq<'T> @@ -1403,7 +1357,7 @@ module Seq = /// /// The returned sequence may be passed between threads safely. However, /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. - /// Iteration can continue up to Int32.MaxValue. + /// Iteration can continue up to Int32.MaxValue. This is an O(1) operation. /// /// A function that generates an item in the sequence from a given index. /// @@ -1415,8 +1369,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 5; 6; 7; 8; ... } /// - /// - /// This is an O(1) operation. [] val initInfinite: initializer: (int -> 'T) -> seq<'T> @@ -1588,7 +1540,7 @@ module Seq = /// object. /// /// The returned sequence may be passed between threads safely. However, - /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. + /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. /// /// A function to transform items from the input sequence. /// The input sequence. @@ -1605,8 +1557,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 1; 3; 2 } /// - /// - /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val map: mapping: ('T -> 'U) -> source: seq<'T> -> seq<'U> @@ -1640,7 +1590,7 @@ module Seq = /// to each of the elements of the collection. The function is also used to accumulate a final value. /// /// This function digests the whole initial sequence as soon as it is called. As a result this function should - /// not be used with large or infinite sequences. + /// not be used with large or infinite sequences. This is an O(n) operation, where n is the length of the sequence. /// /// The function to transform elements from the input collection and accumulate the final value. /// The initial state. @@ -1666,8 +1616,6 @@ module Seq = /// /// Evaluates newCharges to seq { In 2; Out 4; In 6 } and balance to 2. /// - /// - /// This is an O(n) operation, where n is the length of the sequence. [] val mapFold<'T, 'State, 'Result> : mapping: ('State -> 'T -> 'Result * 'State) -> state: 'State -> source: seq<'T> -> seq<'Result> * 'State @@ -1676,7 +1624,7 @@ module Seq = /// to each of the elements of the collection. The function is also used to accumulate a final value. /// /// This function digests the whole initial sequence as soon as it is called. As a result this function should - /// not be used with large or infinite sequences. + /// not be used with large or infinite sequences. This is an O(n) operation, where n is the length of the sequence. /// /// The function to transform elements from the input collection and accumulate the final value. /// The input collection. @@ -1702,8 +1650,6 @@ module Seq = /// /// Evaluates newCharges to seq { In 2; Out 4; In 6 } and balance to 2. /// - /// - /// This is an O(n) operation, where n is the length of the sequence. [] val mapFoldBack<'T, 'State, 'Result> : mapping: ('T -> 'State -> 'Result * 'State) -> source: seq<'T> -> state: 'State -> seq<'Result> * 'State @@ -1992,7 +1938,7 @@ module Seq = /// Returns a sequence with all elements permuted according to the /// specified permutation. /// - /// This function consumes the whole input sequence before yielding the first element of the result sequence. + /// This function consumes the whole input sequence before yielding the first element of the result sequence. This is an O(n) operation, where n is the length of the sequence. /// /// The function that maps input indices to output indices. /// The input sequence. @@ -2010,8 +1956,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 4; 1; 2; 3 }. /// - /// - /// This is an O(n) operation, where n is the length of the sequence. [] val permute: indexMap: (int -> int) -> source: seq<'T> -> seq<'T> @@ -2141,7 +2085,7 @@ module Seq = /// Thrown when the input sequence is null. /// Thrown when the input sequence is empty. /// - /// This function consumes the whole input sequence before returning the result. + /// This function consumes the whole input sequence before returning the result. This is an O(n) operation, where n is the length of the sequence. /// /// /// @@ -2151,8 +2095,6 @@ module Seq = /// /// Evaluates to 2431, by computing 1 + (3 + (4 + 2 * 10) * 10) * 10 /// - /// - /// This is an O(n) operation, where n is the length of the sequence. [] val reduceBack: reduction: ('T -> 'T -> 'T) -> source: seq<'T> -> 'T @@ -2164,7 +2106,7 @@ module Seq = /// /// Thrown when the input sequence is null. /// - /// This function consumes the whole input sequence before yielding the first element of the reversed sequence. + /// This function consumes the whole input sequence before yielding the first element of the reversed sequence. This is an O(n) operation, where n is the length of the sequence. /// /// /// @@ -2174,8 +2116,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 2; 1; 0 }. /// - /// - /// This is an O(n) operation, where n is the length of the sequence. [] val rev: source: seq<'T> -> seq<'T> @@ -2334,7 +2274,7 @@ module Seq = /// large or infinite sequences. /// /// The function makes no assumption on the ordering of the original - /// sequence and uses a stable sort, that is the original order of equal elements is preserved. + /// sequence and uses a stable sort, that is the original order of equal elements is preserved. This is an O(n log n) operation, where n is the length of the sequence. /// /// The input sequence. /// @@ -2350,8 +2290,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 1; 1 3; 4; 6; 8 }. /// - /// - /// This is an O(n log n) operation, where n is the length of the sequence. [] val sort: source: seq<'T> -> seq<'T> when 'T: comparison @@ -2362,7 +2300,7 @@ module Seq = /// large or infinite sequences. /// /// The function makes no assumption on the ordering of the original - /// sequence and uses a stable sort, that is the original order of equal elements is preserved. + /// sequence and uses a stable sort, that is the original order of equal elements is preserved. This is an O(n log n) operation, where n is the length of the sequence. /// /// The function to compare the collection elements. /// The input sequence. @@ -2382,8 +2320,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { (0, "aa"); (2, "cc"); (3, "dd"); (1, "bbb") }. /// - /// - /// This is an O(n log n) operation, where n is the length of the sequence. [] val sortWith: comparer: ('T -> 'T -> int) -> source: seq<'T> -> seq<'T> @@ -2395,7 +2331,7 @@ module Seq = /// large or infinite sequences. /// /// The function makes no assumption on the ordering of the original - /// sequence and uses a stable sort, that is the original order of equal elements is preserved. + /// sequence and uses a stable sort, that is the original order of equal elements is preserved. This is an O(n log n) operation, where n is the length of the sequence. /// /// A function to transform items of the input sequence into comparable keys. /// The input sequence. @@ -2412,8 +2348,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { "a"; "dd"; "bbb"; "cccc" }. /// - /// - /// This is an O(n log n) operation, where n is the length of the sequence. [] val sortBy: projection: ('T -> 'Key) -> source: seq<'T> -> seq<'T> when 'Key: comparison @@ -2424,7 +2358,7 @@ module Seq = /// large or infinite sequences. The function makes no assumption on the ordering of the original /// sequence. /// - /// This is a stable sort, that is the original order of equal elements is preserved. + /// This is a stable sort, that is the original order of equal elements is preserved. This is an O(n log n) operation, where n is the length of the sequence. /// /// The input sequence. /// @@ -2440,8 +2374,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 8; 6; 4; 3; 1; 1 }. /// - /// - /// This is an O(n log n) operation, where n is the length of the sequence. [] val inline sortDescending: source: seq<'T> -> seq<'T> when 'T: comparison @@ -2453,7 +2385,7 @@ module Seq = /// large or infinite sequences. The function makes no assumption on the ordering of the original /// sequence. /// - /// This is a stable sort, that is the original order of equal elements is preserved. + /// This is a stable sort, that is the original order of equal elements is preserved. This is an O(n log n) operation, where n is the length of the sequence. /// /// A function to transform items of the input sequence into comparable keys. /// The input sequence. @@ -2470,8 +2402,6 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { "cccc"; "bbb"; "dd"; "a" }. /// - /// - /// This is an O(n log n) operation, where n is the length of the sequence. [] val inline sortByDescending: projection: ('T -> 'Key) -> source: seq<'T> -> seq<'T> when 'Key: comparison @@ -2496,7 +2426,7 @@ module Seq = /// Returns the sum of the results generated by applying the function to each element of the sequence. /// - /// The generated elements are summed using the + operator and Zero property associated with the generated type. + /// The generated elements are summed using the + operator and Zero property associated with the generated type. This is an O(n) operation, where n is the length of the sequence. /// /// A function to transform items from the input sequence into the type that will be summed. /// The input sequence. @@ -2511,8 +2441,6 @@ module Seq = /// /// Evaluates to 7. /// - /// - /// This is an O(n) operation, where n is the length of the sequence. [] val inline sumBy: projection: ('T -> ^U) -> source: seq<'T> -> ^U @@ -2546,7 +2474,7 @@ module Seq = /// /// Throws InvalidOperationException /// if the count exceeds the number of elements in the sequence. Seq.truncate - /// returns as many items as the sequence contains instead of throwing an exception. + /// returns as many items as the sequence contains instead of throwing an exception. Sequence construction is O(1). Enumeration is O(count). /// /// The number of items to take. /// The input sequence. @@ -2584,8 +2512,6 @@ module Seq = /// /// Evaluates to a sequence yielding no results. /// - /// - /// Sequence construction is O(1). Enumeration is O(count). [] val take: count: int -> source: seq<'T> -> seq<'T> @@ -2688,7 +2614,7 @@ module Seq = /// Return None if no such element exists. /// /// This function digests the whole initial sequence as soon as it is called. As a - /// result this function should not be used with large or infinite sequences. + /// result this function should not be used with large or infinite sequences. This is an O(n) operation in the worst case, where n is the length of the sequence. /// /// A function that evaluates to a Boolean when given an item in the sequence. /// The input sequence. @@ -2714,8 +2640,6 @@ module Seq = /// /// Evaluates to None /// - /// - /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val tryFindBack: predicate: ('T -> bool) -> source: seq<'T> -> 'T option @@ -2786,7 +2710,7 @@ module Seq = /// that satisfies the given predicate. Return None if no such element exists. /// /// This function digests the whole initial sequence as soon as it is called. As a - /// result this function should not be used with large or infinite sequences. + /// result this function should not be used with large or infinite sequences. This is an O(n) operation in the worst case, where n is the length of the sequence. /// /// A function that evaluates to a Boolean when given an item in the sequence. /// The input sequence. @@ -2812,8 +2736,6 @@ module Seq = /// /// Evaluates to None /// - /// - /// This is an O(n) operation in the worst case, where n is the length of the sequence. [] val tryFindIndexBack: predicate: ('T -> bool) -> source: seq<'T> -> int option @@ -2853,7 +2775,7 @@ module Seq = /// /// This function returns a sequence that digests the whole initial sequence as soon as /// that sequence is iterated. As a result this function should not be used with - /// large or infinite sequences. + /// large or infinite sequences. This is an O(n*m) operation, where n and m are the dimensions. /// /// The input sequence. /// @@ -2871,8 +2793,6 @@ module Seq = /// /// Evaluates to a sequence of sequences yielding the same results as [ [10; 11]; [20; 21]; [30; 31] ]. /// - /// - /// This is an O(n*m) operation, where n and m are the dimensions. [] val transpose: source: seq<'Collection> -> seq> when 'Collection :> seq<'T> @@ -2922,7 +2842,7 @@ module Seq = /// generator, until a None value is returned by the element generator. Each call to the element /// generator returns a new residual state. /// - /// The stream will be recomputed each time an IEnumerator is requested and iterated for the Seq. + /// The stream will be recomputed each time an IEnumerator is requested and iterated for the Seq. This is an O(n) operation, where n is the number of elements generated. /// /// A function that takes in the current state and returns an option tuple of the next /// element of the sequence and the next state value. @@ -2943,8 +2863,6 @@ module Seq = /// /// Evaluates to an infinite sequence yielding the results seq { 1I; 2I; 4I; 8I; ... } /// - /// - /// This is an O(n) operation, where n is the number of elements generated. [] val unfold: generator: ('State -> ('T * 'State) option) -> state: 'State -> seq<'T> From 7806d13e58b53125e54b4ac06195ba4ea4709b71 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jan 2026 20:34:17 +0100 Subject: [PATCH 10/17] Add complexity remarks to remaining 11 Seq functions Complete coverage: 118/118 functions now have complexity remarks Added remarks for: - indexed: Sequence construction is O(1), Enumeration is O(n) - length: O(n) eager operation - ofList: O(1) view operation - replicate: O(1) construction, O(count) enumeration - scanBack: O(n) eager, consumes whole sequence - toArray: O(n) eager materialization - removeAt: O(n) where n is the index - updateAt: O(n) where n is the index - insertManyAt: O(n) where n is the index - average: O(n) eager operation - contains: O(n) eager operation Build: 0 errors, 0 warnings XmlDocumentationValidation test: PASSED --- src/FSharp.Core/seq.fsi | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/FSharp.Core/seq.fsi b/src/FSharp.Core/seq.fsi index 80e7fd16ba9..8f6a30a5455 100644 --- a/src/FSharp.Core/seq.fsi +++ b/src/FSharp.Core/seq.fsi @@ -84,6 +84,8 @@ module Seq = /// /// Throws ArgumentException /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val inline average: source: seq< ^T > -> ^T @@ -413,6 +415,8 @@ module Seq = /// [1; 2] |> Seq.contains 5 // evaluates to false /// /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val inline contains: value: 'T -> source: seq<'T> -> bool when 'T: equality @@ -1315,6 +1319,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { (0, "a"); (1, "b"); (2, "c") } /// + /// + /// Sequence construction is O(1). Enumeration is O(n), where n is the length of the sequence. [] val indexed: source: seq<'T> -> seq @@ -1531,6 +1537,8 @@ module Seq = /// /// Evaluates to 3 /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val length: source: seq<'T> -> int @@ -1909,6 +1917,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 1; 2; 5 }. /// + /// + /// This is an O(1) operation. [] val ofList: source: 'T list -> seq<'T> @@ -2069,6 +2079,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { "a"; "a"; "a" }. /// + /// + /// Sequence construction is O(1). Enumeration is O(count). [] val replicate: count: int -> initial: 'T -> seq<'T> @@ -2181,6 +2193,8 @@ module Seq = /// state, 3 the next state, 1 the next state, and 2 the final state, and the states /// are produced from back to front. /// + /// + /// This function consumes the whole input sequence before returning the result. This is an O(n) operation, where n is the length of the sequence. [] val scanBack<'T, 'State> : folder: ('T -> 'State -> 'State) -> source: seq<'T> -> state: 'State -> seq<'State> @@ -2554,6 +2568,8 @@ module Seq = /// /// Evaluates to [| 1; 2; 5 |]. /// + /// + /// This is an O(n) operation, where n is the length of the sequence. [] val toArray: source: seq<'T> -> 'T array @@ -2956,6 +2972,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 0; 2 }. /// + /// + /// This is an O(n) operation, where n is the index. [] val removeAt: index: int -> source: seq<'T> -> seq<'T> @@ -2996,6 +3014,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 0; 9; 2 }. /// + /// + /// This is an O(n) operation, where n is the index. [] val updateAt: index: int -> value: 'T -> source: seq<'T> -> seq<'T> @@ -3036,6 +3056,8 @@ module Seq = /// /// Evaluates to a sequence yielding the same results as seq { 0; 8; 9; 1; 2 }. /// + /// + /// This is an O(n) operation, where n is the index. [] val insertManyAt: index: int -> values: seq<'T> -> source: seq<'T> -> seq<'T> From 7d2f7b26f5f51e2dd2391cdccfde2495f7493fdc Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jan 2026 20:43:52 +0100 Subject: [PATCH 11/17] Fix duplicate tags in Seq.average and Seq.scanBack - Remove duplicate complexity remarks from average function - Merge duplicate remarks content into single tag for scanBack function - Verified: Build passes with 0 errors, XmlDocumentationValidation test passes --- src/FSharp.Core/seq.fsi | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/FSharp.Core/seq.fsi b/src/FSharp.Core/seq.fsi index 8f6a30a5455..ecdf6d76a01 100644 --- a/src/FSharp.Core/seq.fsi +++ b/src/FSharp.Core/seq.fsi @@ -84,8 +84,6 @@ module Seq = /// /// Throws ArgumentException /// - /// - /// This is an O(n) operation, where n is the length of the sequence. [] val inline average: source: seq< ^T > -> ^T @@ -2166,7 +2164,7 @@ module Seq = /// /// This function returns a sequence that digests the whole initial sequence as soon as that /// sequence is iterated. As a result this function should not be used with large or infinite sequences. - /// + /// This function consumes the whole input sequence before returning the result. This is an O(n) operation, where n is the length of the sequence. /// /// A function that updates the state with each element from the sequence. /// The input sequence. @@ -2193,8 +2191,6 @@ module Seq = /// state, 3 the next state, 1 the next state, and 2 the final state, and the states /// are produced from back to front. /// - /// - /// This function consumes the whole input sequence before returning the result. This is an O(n) operation, where n is the length of the sequence. [] val scanBack<'T, 'State> : folder: ('T -> 'State -> 'State) -> source: seq<'T> -> state: 'State -> seq<'State> From cd7b2192cc56ef9865af847127ba526313599965 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jan 2026 20:52:51 +0100 Subject: [PATCH 12/17] Add missing complexity remarks to delay, empty, nth, and sum in seq.fsi - delay: O(1) construction, enumeration cost depends on generated sequence - empty: O(1) operation - nth: O(n) where n is the index - sum: O(n) where n is the length of the sequence This completes 100% coverage: 118/118 Seq functions now have complexity remarks. --- src/FSharp.Core/seq.fsi | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/FSharp.Core/seq.fsi b/src/FSharp.Core/seq.fsi index ecdf6d76a01..20ea0cc64e6 100644 --- a/src/FSharp.Core/seq.fsi +++ b/src/FSharp.Core/seq.fsi @@ -451,7 +451,7 @@ module Seq = /// sequence. /// /// The input function is evaluated each time an IEnumerator for the sequence - /// is requested. + /// is requested. Sequence construction is O(1). Enumeration cost depends on the generated sequence. /// /// The generating function for the sequence. /// The result sequence. @@ -546,6 +546,8 @@ module Seq = /// Creates an empty sequence. /// + /// This is an O(1) operation. + /// /// An empty sequence. /// /// @@ -1869,6 +1871,8 @@ module Seq = /// Computes the nth element in the collection. /// + /// This is an O(n) operation, where n is the index. + /// /// The index of element to retrieve. /// The input sequence. /// @@ -2417,7 +2421,7 @@ module Seq = /// Returns the sum of the elements in the sequence. /// - /// The elements are summed using the + operator and Zero property associated with the generated type. + /// The elements are summed using the + operator and Zero property associated with the generated type. This is an O(n) operation, where n is the length of the sequence. /// /// The input sequence. /// From f9d5d89b99d89b7b8ee29bb7632bbea419e3af50 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jan 2026 21:01:45 +0100 Subject: [PATCH 13/17] Add complexity remarks to list Cons operator in prim-types.fsi - Added O(1) complexity remark to static member Cons (:: operator) Complexity documentation summary: - set.fsi: 47 remarks - map.fsi: 43 remarks - list.fsi: 117 remarks - array.fsi: 164 remarks - seq.fsi: 118 remarks - prim-types.fsi: 3 remarks (Item, Cons, @) Total: 492 complexity remarks across 6 files --- src/FSharp.Core/prim-types.fsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/FSharp.Core/prim-types.fsi b/src/FSharp.Core/prim-types.fsi index 5e83b8957fe..029c7f8dd90 100644 --- a/src/FSharp.Core/prim-types.fsi +++ b/src/FSharp.Core/prim-types.fsi @@ -2724,6 +2724,8 @@ namespace Microsoft.FSharp.Collections /// The existing list. /// /// The list with head appended to the front of tail. + /// + /// This is an O(1) operation. static member Cons: head: 'T * tail: 'T list -> 'T list interface IEnumerable<'T> From 59f773ae59c6c707e57a1a414c7be90a8ef40b39 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 23 Jan 2026 09:44:57 +0100 Subject: [PATCH 14/17] update --- .gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index 4d8614da8fb..d9a2e5384de 100644 --- a/.gitignore +++ b/.gitignore @@ -158,6 +158,3 @@ tests/projects/CompilerCompat/local-nuget-packages/ tests/projects/CompilerCompat/lib-output-*/ tests/projects/CompilerCompat/**/bin/ tests/projects/CompilerCompat/**/obj/ - -# Complexity documentation working folder (not to be committed) -complexity/ From 9feebce47a8ce14d64cef39646ca88fd422575cd Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 23 Jan 2026 09:51:45 +0100 Subject: [PATCH 15/17] Update 10.0.200.md --- docs/release-notes/.FSharp.Core/10.0.200.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/.FSharp.Core/10.0.200.md b/docs/release-notes/.FSharp.Core/10.0.200.md index 729add7c4be..64590620bad 100644 --- a/docs/release-notes/.FSharp.Core/10.0.200.md +++ b/docs/release-notes/.FSharp.Core/10.0.200.md @@ -5,4 +5,5 @@ ### Changed * Added `not null` constraints to `IDelegateEvent<'Delegate>`, `IEvent<'Delegate,'Args>`, `DelegateEvent<'Delegate>`, and `Event<'Delegate,'Args>` types to prevent spurious nullness warnings when implementing CLIEvent properties. ([Issue #18361](https://github.com/dotnet/fsharp/issues/18361), [Issue #18349](https://github.com/dotnet/fsharp/issues/18349), [PR #19221](https://github.com/dotnet/fsharp/pull/19221)) -* Renamed deprecated `or` and `&` operators, but keeping the original compiled names for binary compatibility. ([PR #19143](https://github.com/dotnet/fsharp/pull/19143)) \ No newline at end of file +* Renamed deprecated `or` and `&` operators, but keeping the original compiled names for binary compatibility. ([PR #19143](https://github.com/dotnet/fsharp/pull/19143)) +* Added complexity documentation (Big-O notation) to all 462 functions across Array, List, Seq, Map, and Set collection modules. ([PR #19240](https://github.com/dotnet/fsharp/pull/19240)) \ No newline at end of file From 2ba17c2ca98b0103661ac160de830f00975d1499 Mon Sep 17 00:00:00 2001 From: GH Actions Date: Fri, 23 Jan 2026 09:06:05 +0000 Subject: [PATCH 16/17] Apply patch from /run fantomas --- src/FSharp.Core/array.fsi | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/FSharp.Core/array.fsi b/src/FSharp.Core/array.fsi index e3821fc8a5b..9db69d8eb89 100644 --- a/src/FSharp.Core/array.fsi +++ b/src/FSharp.Core/array.fsi @@ -3849,7 +3849,7 @@ module Array = /// Returns the greatest of all elements of the array, compared via Operators.max. /// - /// Throws ArgumentException for empty arrays. This is an O(n) operation, where n is the length of the array. + /// Throws ArgumentException for empty arrays. This is an O(n) operation, where n is the length of the array. /// /// The input array. /// @@ -3880,7 +3880,7 @@ module Array = /// Returns the greatest of all elements of the array, compared via Operators.max on the function result. /// - /// Throws ArgumentException for empty arrays. This is an O(n) operation, where n is the length of the array. + /// Throws ArgumentException for empty arrays. This is an O(n) operation, where n is the length of the array. /// /// The function to transform the elements into a type supporting comparison. /// The input array. @@ -3912,7 +3912,7 @@ module Array = /// Returns the smallest of all elements of the array, compared via Operators.min. /// - /// Throws ArgumentException for empty arrays This is an O(n) operation, where n is the length of the array. + /// Throws ArgumentException for empty arrays This is an O(n) operation, where n is the length of the array. /// /// The input array. /// @@ -3943,7 +3943,7 @@ module Array = /// Returns the lowest of all elements of the array, compared via Operators.min on the function result. /// - /// Throws ArgumentException for empty arrays. This is an O(n) operation, where n is the length of the array. + /// Throws ArgumentException for empty arrays. This is an O(n) operation, where n is the length of the array. /// /// The function to transform the elements into a type supporting comparison. /// The input array. @@ -3989,8 +3989,8 @@ module Array = /// /// Evaluates to 11. /// - /// - /// This is an O(n) operation, where n is the length of the array. + /// + /// This is an O(n) operation, where n is the length of the array. [] val inline sum: array: ^T array -> ^T when ^T: (static member (+): ^T * ^T -> ^T) and ^T: (static member Zero: ^T) @@ -4464,8 +4464,8 @@ module Array = /// /// After evaluation array contains [| 1; 1; 3; 4; 6; 8 |]. /// - /// - /// This is an O(n log n) operation, modifying the array in place. + /// + /// This is an O(n log n) operation, modifying the array in place. [] val sortInPlace: array: 'T array -> unit when 'T: comparison From a76cde61a0ae1f80c5265f4ab214639dc0d55ba8 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 23 Jan 2026 17:52:00 +0100 Subject: [PATCH 17/17] Update printing test baselines for List.map complexity documentation --- tests/fsharp/core/printing/output.1000.stdout.bsl | 3 +++ tests/fsharp/core/printing/output.200.stdout.bsl | 3 +++ tests/fsharp/core/printing/output.47.stdout.bsl | 3 +++ tests/fsharp/core/printing/output.multiemit.stdout.bsl | 3 +++ tests/fsharp/core/printing/output.off.stdout.bsl | 3 +++ tests/fsharp/core/printing/output.stdout.bsl | 3 +++ 6 files changed, 18 insertions(+) diff --git a/tests/fsharp/core/printing/output.1000.stdout.bsl b/tests/fsharp/core/printing/output.1000.stdout.bsl index 95999b932f9..bafd9bb25a2 100644 --- a/tests/fsharp/core/printing/output.1000.stdout.bsl +++ b/tests/fsharp/core/printing/output.1000.stdout.bsl @@ -1118,6 +1118,9 @@ Description: Builds a new collection whose elements are the results of applying the given function to each of the elements of the collection. +Remarks: +This is an O(n) operation, where n is the length of the list. + Parameters: - mapping: The function to transform elements from the input list. - list: The input list. diff --git a/tests/fsharp/core/printing/output.200.stdout.bsl b/tests/fsharp/core/printing/output.200.stdout.bsl index 3622aeecd1e..b2f769d0b83 100644 --- a/tests/fsharp/core/printing/output.200.stdout.bsl +++ b/tests/fsharp/core/printing/output.200.stdout.bsl @@ -438,6 +438,9 @@ Description: Builds a new collection whose elements are the results of applying the given function to each of the elements of the collection. +Remarks: +This is an O(n) operation, where n is the length of the list. + Parameters: - mapping: The function to transform elements from the input list. - list: The input list. diff --git a/tests/fsharp/core/printing/output.47.stdout.bsl b/tests/fsharp/core/printing/output.47.stdout.bsl index 874b7915a68..a6b19a1ab53 100644 --- a/tests/fsharp/core/printing/output.47.stdout.bsl +++ b/tests/fsharp/core/printing/output.47.stdout.bsl @@ -4075,6 +4075,9 @@ Description: Builds a new collection whose elements are the results of applying the given function to each of the elements of the collection. +Remarks: +This is an O(n) operation, where n is the length of the list. + Parameters: - mapping: The function to transform elements from the input list. - list: The input list. diff --git a/tests/fsharp/core/printing/output.multiemit.stdout.bsl b/tests/fsharp/core/printing/output.multiemit.stdout.bsl index 8080bcbf73b..8a7c1ed3e4b 100644 --- a/tests/fsharp/core/printing/output.multiemit.stdout.bsl +++ b/tests/fsharp/core/printing/output.multiemit.stdout.bsl @@ -4077,6 +4077,9 @@ Description: Builds a new collection whose elements are the results of applying the given function to each of the elements of the collection. +Remarks: +This is an O(n) operation, where n is the length of the list. + Parameters: - mapping: The function to transform elements from the input list. - list: The input list. diff --git a/tests/fsharp/core/printing/output.off.stdout.bsl b/tests/fsharp/core/printing/output.off.stdout.bsl index 172e67e2436..17a3f6aca61 100644 --- a/tests/fsharp/core/printing/output.off.stdout.bsl +++ b/tests/fsharp/core/printing/output.off.stdout.bsl @@ -265,6 +265,9 @@ Description: Builds a new collection whose elements are the results of applying the given function to each of the elements of the collection. +Remarks: +This is an O(n) operation, where n is the length of the list. + Parameters: - mapping: The function to transform elements from the input list. - list: The input list. diff --git a/tests/fsharp/core/printing/output.stdout.bsl b/tests/fsharp/core/printing/output.stdout.bsl index 8080bcbf73b..8a7c1ed3e4b 100644 --- a/tests/fsharp/core/printing/output.stdout.bsl +++ b/tests/fsharp/core/printing/output.stdout.bsl @@ -4077,6 +4077,9 @@ Description: Builds a new collection whose elements are the results of applying the given function to each of the elements of the collection. +Remarks: +This is an O(n) operation, where n is the length of the list. + Parameters: - mapping: The function to transform elements from the input list. - list: The input list.