@@ -2999,6 +2999,13 @@ 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) best case (attribute set already sorted)
3006+ - O(n log n) worst case (requires sorting), where:
3007+
3008+ n = number of attributes in the set
30023009 )" ,
30033010 .fun = prim_attrNames,
30043011});
@@ -3031,6 +3038,13 @@ static RegisterPrimOp primop_attrValues({
30313038 .doc = R"(
30323039 Return the values of the attributes in the set *set* in the order
30333040 corresponding to the sorted attribute names.
3041+
3042+ ## Time Complexity
3043+
3044+ - O(n) best case (attribute set already sorted)
3045+ - O(n log n) worst case (requires sorting), where:
3046+
3047+ n = number of attributes in the set
30343048 )" ,
30353049 .fun = prim_attrValues,
30363050});
@@ -3056,6 +3070,10 @@ static RegisterPrimOp primop_getAttr({
30563070 aborts if the attribute doesn’t exist. This is a dynamic version of
30573071 the `.` operator, since *s* is an expression rather than an
30583072 identifier.
3073+
3074+ # Time Complexity
3075+
3076+ O(log n) where n = number of attributes in the set
30593077 )" ,
30603078 .fun = prim_getAttr,
30613079});
@@ -3144,6 +3162,10 @@ static RegisterPrimOp primop_hasAttr({
31443162 `hasAttr` returns `true` if *set* has an attribute named *s*, and
31453163 `false` otherwise. This is a dynamic version of the `?` operator,
31463164 since *s* is an expression rather than an identifier.
3165+
3166+ # Time Complexity
3167+
3168+ O(log n) where n = number of attributes in the set
31473169 )" ,
31483170 .fun = prim_hasAttr,
31493171});
@@ -3203,6 +3225,13 @@ static RegisterPrimOp primop_removeAttrs({
32033225 ```
32043226
32053227 evaluates to `{ y = 2; }`.
3228+
3229+ # Time Complexity
3230+
3231+ O(n + k log k) where:
3232+
3233+ n = number of attributes in input set
3234+ k = number of attribute names to remove
32063235 )" ,
32073236 .fun = prim_removeAttrs,
32083237});
@@ -3290,6 +3319,10 @@ static RegisterPrimOp primop_listToAttrs({
32903319 ```nix
32913320 { foo = 123; bar = 456; }
32923321 ```
3322+
3323+ # Time Complexity
3324+
3325+ O(n log n) where n = number of list elements
32933326 )" ,
32943327 .fun = prim_listToAttrs,
32953328});
@@ -3366,7 +3399,12 @@ static RegisterPrimOp primop_intersectAttrs({
33663399 Return a set consisting of the attributes in the set *e2* which have the
33673400 same name as some attribute in *e1*.
33683401
3369- Performs in O(*n* log *m*) where *n* is the size of the smaller set and *m* the larger set's size.
3402+ # Time Complexity
3403+
3404+ O(n * log m) where:
3405+
3406+ n = number of attributes in the smaller set
3407+ m = number of attributes in the larger set
33703408 )" ,
33713409 .fun = prim_intersectAttrs,
33723410});
@@ -3406,6 +3444,13 @@ static RegisterPrimOp primop_catAttrs({
34063444 ```
34073445
34083446 evaluates to `[1 2]`.
3447+
3448+ # Time Complexity
3449+
3450+ O(n * log m) where:
3451+
3452+ n = number of sets in input list
3453+ m = average number of attributes per set
34093454 )" ,
34103455 .fun = prim_catAttrs,
34113456});
@@ -3449,6 +3494,10 @@ static RegisterPrimOp primop_functionArgs({
34493494 "Formal argument" here refers to the attributes pattern-matched by
34503495 the function. Plain lambdas are not included, e.g. `functionArgs (x:
34513496 ...) = { }`.
3497+
3498+ # Time Complexity
3499+
3500+ O(n) where n = number of formal arguments
34523501 )" ,
34533502 .fun = prim_functionArgs,
34543503});
@@ -3481,6 +3530,13 @@ static RegisterPrimOp primop_mapAttrs({
34813530 ```
34823531
34833532 evaluates to `{ a = 10; b = 20; }`.
3533+
3534+ # Time Complexity
3535+
3536+ O(n * T_f) where:
3537+
3538+ n = number of attributes
3539+ T_f = function evaluation time
34843540 )" ,
34853541 .fun = prim_mapAttrs,
34863542});
@@ -3568,6 +3624,15 @@ static RegisterPrimOp primop_zipAttrsWith({
35683624 b = { name = "b"; values = [ "z" ]; };
35693625 }
35703626 ```
3627+
3628+ # Time Complexity
3629+
3630+ O(n * k * log k) worst case, where:
3631+
3632+ n = number of attribute sets in input list
3633+ k = number of unique keys across all sets
3634+
3635+ More precisely: O(n * m * log k) where m ≤ k is average number of attributes per set
35713636 )" ,
35723637 .fun = prim_zipAttrsWith,
35733638});
@@ -3633,6 +3698,10 @@ static RegisterPrimOp primop_head({
36333698 Return the first element of a list; abort evaluation if the argument
36343699 isn’t a list or is an empty list. You can test whether a list is
36353700 empty by comparing it with `[]`.
3701+
3702+ # Time Complexity
3703+
3704+ O(1)
36363705 )" ,
36373706 .fun = prim_head,
36383707});
@@ -3664,6 +3733,10 @@ static RegisterPrimOp primop_tail({
36643733 > This function should generally be avoided since it's inefficient:
36653734 > unlike Haskell's `tail`, it takes O(n) time, so recursing over a
36663735 > list by repeatedly calling `tail` takes O(n^2) time.
3736+
3737+ # Time Complexity
3738+
3739+ O(n) where n = list length (must copy n-1 elements)
36673740 )" ,
36683741 .fun = prim_tail,
36693742});
@@ -3698,6 +3771,13 @@ static RegisterPrimOp primop_map({
36983771 ```
36993772
37003773 evaluates to `[ "foobar" "foobla" "fooabc" ]`.
3774+
3775+ # Time Complexity
3776+
3777+ O(n * T_f) where:
3778+
3779+ n = list length
3780+ T_f = function evaluation time
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 average element
3867+
3868+ returns early if the elements is found
37733869 )" ,
37743870 .fun = prim_elem,
37753871});
@@ -3792,6 +3888,13 @@ 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(k + N) where:
3895+
3896+ k = number of input lists
3897+ N = total number of elements across all lists
37953898 )" ,
37963899 .fun = prim_concatLists,
37973900});
@@ -3808,6 +3911,10 @@ static RegisterPrimOp primop_length({
38083911 .args = {" e" },
38093912 .doc = R"(
38103913 Return the length of the list *e*.
3914+
3915+ # Time Complexity
3916+
3917+ O(1)
38113918 )" ,
38123919 .fun = prim_length,
38133920});
@@ -3851,6 +3958,13 @@ static RegisterPrimOp primop_foldlStrict({
38513958 argument is the current element being processed. The return value
38523959 of each application of `op` is evaluated immediately, even for
38533960 intermediate values.
3961+
3962+ # Time Complexity
3963+
3964+ O(n * T_f) where:
3965+
3966+ n = list length
3967+ T_f = fold function evaluation time
38543968 )" ,
38553969 .fun = prim_foldlStrict,
38563970});
@@ -3889,6 +4003,15 @@ static RegisterPrimOp primop_any({
38894003 .doc = R"(
38904004 Return `true` if the function *pred* returns `true` for at least one
38914005 element of *list*, and `false` otherwise.
4006+
4007+ ## Time Complexity
4008+
4009+ O(n * T_f) where:
4010+
4011+ - n = list length
4012+ - T_f = predicate evaluation time
4013+
4014+ returns early when predicate returns true
38924015 )" ,
38934016 .fun = prim_any,
38944017});
@@ -3904,6 +4027,13 @@ static RegisterPrimOp primop_all({
39044027 .doc = R"(
39054028 Return `true` if the function *pred* returns `true` for all elements
39064029 of *list*, and `false` otherwise.
4030+
4031+ ## Time Complexity
4032+
4033+ O(n * T_f) where:
4034+
4035+ - n = list length
4036+ - T_f = predicate evaluation time
39074037 )" ,
39084038 .fun = prim_all,
39094039});
@@ -3942,6 +4072,13 @@ static RegisterPrimOp primop_genList({
39424072 ```
39434073
39444074 returns the list `[ 0 1 4 9 16 ]`.
4075+
4076+ # Time Complexity
4077+
4078+ O(n * T_f) where:
4079+
4080+ n = requested length
4081+ T_f = generator function evaluation time
39454082 )" ,
39464083 .fun = prim_genList,
39474084});
@@ -4036,6 +4173,14 @@ static RegisterPrimOp primop_sort({
40364173
40374174 If the *comparator* violates any of these properties, then `builtins.sort`
40384175 reorders elements in an unspecified manner.
4176+
4177+ # Time Complexity
4178+
4179+ O(n log n * T_cmp) worst case
4180+ O(n * T_cmp) best case (input already sorted), where:
4181+
4182+ n = list length
4183+ T_cmp = comparator evaluation time
40394184 )" ,
40404185 .fun = prim_sort,
40414186});
@@ -4097,6 +4242,13 @@ static RegisterPrimOp primop_partition({
40974242 ```nix
40984243 { right = [ 23 42 ]; wrong = [ 1 9 3 ]; }
40994244 ```
4245+
4246+ # Time Complexity
4247+
4248+ O(n * T_f) where:
4249+
4250+ n = list length
4251+ T_f = predicate evaluation time
41004252 )" ,
41014253 .fun = prim_partition,
41024254});
@@ -4150,7 +4302,17 @@ static RegisterPrimOp primop_groupBy({
41504302 ```nix
41514303 { b = [ "bar" "baz" ]; f = [ "foo" ]; }
41524304 ```
4305+
4306+ # Time Complexity
4307+
4308+ O(N * T_f + N * log k) where:
4309+
4310+ N = number of list elements
4311+ T_f = grouping function evaluation time
4312+ k = number of unique groups
41534313 )" ,
4314+ T_f = grouping function evaluation time
4315+ k = number of unique groups
41544316 .fun = prim_groupBy,
41554317});
41564318
@@ -4192,6 +4354,14 @@ static RegisterPrimOp primop_concatMap({
41924354 .doc = R"(
41934355 This function is equivalent to `builtins.concatLists (map f list)`
41944356 but is more efficient.
4357+
4358+ # Time Complexity
4359+
4360+ O(k * T_f + N) where:
4361+
4362+ k = length of input list
4363+ T_f = time to evaluate function on each element
4364+ N = total elements in all output lists
41954365 )" ,
41964366 .fun = prim_concatMap,
41974367});
@@ -4888,6 +5058,10 @@ static RegisterPrimOp primop_concatStringsSep({
48885058 Concatenate a list of strings with a separator between each
48895059 element, e.g. `concatStringsSep "/" ["usr" "local" "bin"] ==
48905060 "usr/local/bin"`.
5061+
5062+ # Time Complexity
5063+
5064+ O(n) where n = total length of output string
48915065 )" ,
48925066 .fun = prim_concatStringsSep,
48935067});
@@ -4972,6 +5146,14 @@ static RegisterPrimOp primop_replaceStrings({
49725146 ```
49735147
49745148 evaluates to `"fabir"`.
5149+
5150+ # Time Complexity
5151+
5152+ O(n * k * c) where:
5153+
5154+ n = length of input string
5155+ k = number of replacement patterns
5156+ c = average length of patterns in 'from' list
49755157 )" ,
49765158 .fun = prim_replaceStrings,
49775159});
0 commit comments