@@ -2999,6 +2999,12 @@ static RegisterPrimOp primop_attrNames({
29992999 Return the names of the attributes in the set *set* in an
30003000 alphabetically sorted list. For instance, `builtins.attrNames { y
30013001 = 1; x = "foo"; }` evaluates to `[ "x" "y" ]`.
3002+
3003+ # Time Complexity
3004+
3005+ - O(n log n), where:
3006+
3007+ n = number of attributes in the set
30023008 )" ,
30033009 .fun = prim_attrNames,
30043010});
@@ -3031,6 +3037,12 @@ static RegisterPrimOp primop_attrValues({
30313037 .doc = R"(
30323038 Return the values of the attributes in the set *set* in the order
30333039 corresponding to the sorted attribute names.
3040+
3041+ # Time Complexity
3042+
3043+ - O(n log n), where:
3044+
3045+ n = number of attributes in the set
30343046 )" ,
30353047 .fun = prim_attrValues,
30363048});
@@ -3056,6 +3068,10 @@ static RegisterPrimOp primop_getAttr({
30563068 aborts if the attribute doesn’t exist. This is a dynamic version of
30573069 the `.` operator, since *s* is an expression rather than an
30583070 identifier.
3071+
3072+ # Time Complexity
3073+
3074+ O(log n) where n = number of attributes in the set
30593075 )" ,
30603076 .fun = prim_getAttr,
30613077});
@@ -3144,6 +3160,10 @@ static RegisterPrimOp primop_hasAttr({
31443160 `hasAttr` returns `true` if *set* has an attribute named *s*, and
31453161 `false` otherwise. This is a dynamic version of the `?` operator,
31463162 since *s* is an expression rather than an identifier.
3163+
3164+ # Time Complexity
3165+
3166+ O(log n) where n = number of attributes in the set
31473167 )" ,
31483168 .fun = prim_hasAttr,
31493169});
@@ -3203,6 +3223,13 @@ static RegisterPrimOp primop_removeAttrs({
32033223 ```
32043224
32053225 evaluates to `{ y = 2; }`.
3226+
3227+ # Time Complexity
3228+
3229+ O(n + k log k) where:
3230+
3231+ n = number of attributes in input set
3232+ k = number of attribute names to remove
32063233 )" ,
32073234 .fun = prim_removeAttrs,
32083235});
@@ -3290,6 +3317,10 @@ static RegisterPrimOp primop_listToAttrs({
32903317 ```nix
32913318 { foo = 123; bar = 456; }
32923319 ```
3320+
3321+ # Time Complexity
3322+
3323+ O(n log n) where n = number of list elements
32933324 )" ,
32943325 .fun = prim_listToAttrs,
32953326});
@@ -3366,7 +3397,12 @@ static RegisterPrimOp primop_intersectAttrs({
33663397 Return a set consisting of the attributes in the set *e2* which have the
33673398 same name as some attribute in *e1*.
33683399
3369- Performs in O(*n* log *m*) where *n* is the size of the smaller set and *m* the larger set's size.
3400+ # Time Complexity
3401+
3402+ O(n * log m) where:
3403+
3404+ n = number of attributes in the smaller set
3405+ m = number of attributes in the larger set
33703406 )" ,
33713407 .fun = prim_intersectAttrs,
33723408});
@@ -3406,6 +3442,13 @@ static RegisterPrimOp primop_catAttrs({
34063442 ```
34073443
34083444 evaluates to `[1 2]`.
3445+
3446+ # Time Complexity
3447+
3448+ O(n * log m) where:
3449+
3450+ n = number of sets in input list
3451+ m = number of attributes per set
34093452 )" ,
34103453 .fun = prim_catAttrs,
34113454});
@@ -3449,6 +3492,10 @@ static RegisterPrimOp primop_functionArgs({
34493492 "Formal argument" here refers to the attributes pattern-matched by
34503493 the function. Plain lambdas are not included, e.g. `functionArgs (x:
34513494 ...) = { }`.
3495+
3496+ # Time Complexity
3497+
3498+ O(n) where n = number of formal arguments
34523499 )" ,
34533500 .fun = prim_functionArgs,
34543501});
@@ -3481,6 +3528,14 @@ static RegisterPrimOp primop_mapAttrs({
34813528 ```
34823529
34833530 evaluates to `{ a = 10; b = 20; }`.
3531+
3532+ # Time Complexity
3533+
3534+ O(n) where:
3535+
3536+ n = number of attributes
3537+
3538+ Calls to `f` are performed afterwards, when needed
34843539 )" ,
34853540 .fun = prim_mapAttrs,
34863541});
@@ -3568,6 +3623,15 @@ static RegisterPrimOp primop_zipAttrsWith({
35683623 b = { name = "b"; values = [ "z" ]; };
35693624 }
35703625 ```
3626+
3627+ # Time Complexity
3628+
3629+ O(n * k * log k) worst case, where:
3630+
3631+ n = number of attribute sets in input list
3632+ k = number of unique keys across all sets
3633+
3634+ More precisely: O(n * m * log k) where m ≤ k is average number of attributes per set
35713635 )" ,
35723636 .fun = prim_zipAttrsWith,
35733637});
@@ -3633,6 +3697,10 @@ static RegisterPrimOp primop_head({
36333697 Return the first element of a list; abort evaluation if the argument
36343698 isn’t a list or is an empty list. You can test whether a list is
36353699 empty by comparing it with `[]`.
3700+
3701+ # Time Complexity
3702+
3703+ O(1)
36363704 )" ,
36373705 .fun = prim_head,
36383706});
@@ -3664,6 +3732,10 @@ static RegisterPrimOp primop_tail({
36643732 > This function should generally be avoided since it's inefficient:
36653733 > unlike Haskell's `tail`, it takes O(n) time, so recursing over a
36663734 > list by repeatedly calling `tail` takes O(n^2) time.
3735+
3736+ # Time Complexity
3737+
3738+ O(n) where n = list length (copies n-1 elements)
36673739 )" ,
36683740 .fun = prim_tail,
36693741});
@@ -3698,6 +3770,14 @@ static RegisterPrimOp primop_map({
36983770 ```
36993771
37003772 evaluates to `[ "foobar" "foobla" "fooabc" ]`.
3773+
3774+ # Time Complexity
3775+
3776+ O(n) where:
3777+
3778+ n = list length
3779+
3780+ Calls to `f` are performed afterwards when needed.
37013781 )" ,
37023782 .fun = prim_map,
37033783});
@@ -3747,6 +3827,13 @@ static RegisterPrimOp primop_filter({
37473827 .doc = R"(
37483828 Return a list consisting of the elements of *list* for which the
37493829 function *f* returns `true`.
3830+
3831+ # Time Complexity
3832+
3833+ O(n * T_f) where:
3834+
3835+ n = list length
3836+ T_f = predicate evaluation time
37503837 )" ,
37513838 .fun = prim_filter,
37523839});
@@ -3770,6 +3857,15 @@ static RegisterPrimOp primop_elem({
37703857 .doc = R"(
37713858 Return `true` if a value equal to *x* occurs in the list *xs*, and
37723859 `false` otherwise.
3860+
3861+ # Time Complexity
3862+
3863+ O(n * T) (worst case) where:
3864+
3865+ n = list length
3866+ T = time to compare two elements
3867+
3868+ returns early if the elements is found
37733869 )" ,
37743870 .fun = prim_elem,
37753871});
@@ -3792,6 +3888,12 @@ static RegisterPrimOp primop_concatLists({
37923888 .args = {" lists" },
37933889 .doc = R"(
37943890 Concatenate a list of lists into a single list.
3891+
3892+ # Time Complexity
3893+
3894+ O(N) where:
3895+
3896+ N = total number of elements across all lists
37953897 )" ,
37963898 .fun = prim_concatLists,
37973899});
@@ -3808,6 +3910,10 @@ static RegisterPrimOp primop_length({
38083910 .args = {" e" },
38093911 .doc = R"(
38103912 Return the length of the list *e*.
3913+
3914+ # Time Complexity
3915+
3916+ O(1)
38113917 )" ,
38123918 .fun = prim_length,
38133919});
@@ -3851,6 +3957,17 @@ static RegisterPrimOp primop_foldlStrict({
38513957 argument is the current element being processed. The return value
38523958 of each application of `op` is evaluated immediately, even for
38533959 intermediate values.
3960+
3961+ # Time Complexity
3962+
3963+ O(n * T_op) where:
3964+
3965+ n = list length
3966+ T_op = `op` call evaluation time
3967+
3968+ Note: Because foldl' evaluates results only to [WHNF](@docroot@/language/evaluation.md#values),
3969+ deeper parts of values returned by op may be evaluated later.
3970+ Their cost (and errors) therefore may not clearly belong to T_op or to foldl' itself.
38543971 )" ,
38553972 .fun = prim_foldlStrict,
38563973});
@@ -3889,6 +4006,15 @@ static RegisterPrimOp primop_any({
38894006 .doc = R"(
38904007 Return `true` if the function *pred* returns `true` for at least one
38914008 element of *list*, and `false` otherwise.
4009+
4010+ # Time Complexity
4011+
4012+ O(n * T_pred) where:
4013+
4014+ - n = `list` length
4015+ - T_pred = `pred` call evaluation time
4016+
4017+ returns early when `pred` returns `true`
38924018 )" ,
38934019 .fun = prim_any,
38944020});
@@ -3904,6 +4030,13 @@ static RegisterPrimOp primop_all({
39044030 .doc = R"(
39054031 Return `true` if the function *pred* returns `true` for all elements
39064032 of *list*, and `false` otherwise.
4033+
4034+ # Time Complexity
4035+
4036+ O(n * T_f) where:
4037+
4038+ - n = list length
4039+ - T_f = predicate evaluation time
39074040 )" ,
39084041 .fun = prim_all,
39094042});
@@ -3942,6 +4075,14 @@ static RegisterPrimOp primop_genList({
39424075 ```
39434076
39444077 returns the list `[ 0 1 4 9 16 ]`.
4078+
4079+ # Time Complexity
4080+
4081+ O(n) where:
4082+
4083+ n = requested length.
4084+
4085+ Calls to `generator` are performed afterwards, when needed.
39454086 )" ,
39464087 .fun = prim_genList,
39474088});
@@ -4036,6 +4177,13 @@ static RegisterPrimOp primop_sort({
40364177
40374178 If the *comparator* violates any of these properties, then `builtins.sort`
40384179 reorders elements in an unspecified manner.
4180+
4181+ # Time Complexity
4182+
4183+ O(n log n * T_cmp), where:
4184+
4185+ n = `list` length
4186+ T_cmp = `comparator` call evaluation time
40394187 )" ,
40404188 .fun = prim_sort,
40414189});
@@ -4097,6 +4245,13 @@ static RegisterPrimOp primop_partition({
40974245 ```nix
40984246 { right = [ 23 42 ]; wrong = [ 1 9 3 ]; }
40994247 ```
4248+
4249+ # Time Complexity
4250+
4251+ O(n * T_pred) where:
4252+
4253+ n = list length
4254+ T_pred = `pred` call evaluation time
41004255 )" ,
41014256 .fun = prim_partition,
41024257});
@@ -4150,6 +4305,14 @@ static RegisterPrimOp primop_groupBy({
41504305 ```nix
41514306 { b = [ "bar" "baz" ]; f = [ "foo" ]; }
41524307 ```
4308+
4309+ # Time Complexity
4310+
4311+ O(N * T_f + N * log k) where:
4312+
4313+ N = number of `list` elements
4314+ T_f = `f` call evaluation time
4315+ k = number of unique groups
41534316 )" ,
41544317 .fun = prim_groupBy,
41554318});
@@ -4192,6 +4355,14 @@ static RegisterPrimOp primop_concatMap({
41924355 .doc = R"(
41934356 This function is equivalent to `builtins.concatLists (map f list)`
41944357 but is more efficient.
4358+
4359+ # Time Complexity
4360+
4361+ O(k * T_f + N) where:
4362+
4363+ k = length of input list
4364+ T_f = time to call `f` on an element
4365+ N = total number of elements returned by `f` calls
41954366 )" ,
41964367 .fun = prim_concatMap,
41974368});
@@ -4888,6 +5059,10 @@ static RegisterPrimOp primop_concatStringsSep({
48885059 Concatenate a list of strings with a separator between each
48895060 element, e.g. `concatStringsSep "/" ["usr" "local" "bin"] ==
48905061 "usr/local/bin"`.
5062+
5063+ # Time Complexity
5064+
5065+ O(n) where n = total length of output string
48915066 )" ,
48925067 .fun = prim_concatStringsSep,
48935068});
@@ -4972,6 +5147,14 @@ static RegisterPrimOp primop_replaceStrings({
49725147 ```
49735148
49745149 evaluates to `"fabir"`.
5150+
5151+ # Time Complexity
5152+
5153+ O(n * k * c) where:
5154+
5155+ n = length of input string
5156+ k = number of replacement patterns
5157+ c = average length of patterns in 'from' list
49755158 )" ,
49765159 .fun = prim_replaceStrings,
49775160});
0 commit comments