Provide an efficient implementation of ‘elem’
The one in Nixpkgs is O(n^2), this one is O(n). Big reduction in the number of list allocations. Statistics before (on a NixOS system config): time elapsed: 1.17982 size of a value: 24 environments allocated: 1543334 (39624560 bytes) list elements: 9612638 (76901104 bytes) list concatenations: 37434 values allocated: 1854933 (44518392 bytes) attribute sets allocated: 392040 right-biased unions: 186334 values copied in right-biased unions: 591137 symbols in symbol table: 18272 number of thunks: 1392467 number of thunks avoided: 1507311 number of attr lookups: 430801 number of primop calls: 691600 number of function calls: 1492502 Statistics after: time elapsed: 1.08683 size of a value: 24 environments allocated: 1384376 (35809568 bytes) list elements: 6946783 (55574264 bytes) list concatenations: 37434 values allocated: 1760440 (42250560 bytes) attribute sets allocated: 392040 right-biased unions: 186334 values copied in right-biased unions: 591137 symbols in symbol table: 18273 number of thunks: 1297673 number of thunks avoided: 1380759 number of attr lookups: 430802 number of primop calls: 628912 number of function calls: 1333544
This commit is contained in:
		
							parent
							
								
									4ccd48ce24
								
							
						
					
					
						commit
						b9e5b908ed
					
				
					 1 changed files with 17 additions and 2 deletions
				
			
		|  | @ -880,7 +880,8 @@ static void prim_head(EvalState & state, Value * * args, Value & v) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Return a list consisting of everything but the the first element of
 | /* Return a list consisting of everything but the the first element of
 | ||||||
|    a list. */ |    a list.  Warning: this function takes O(n) time, so you probably | ||||||
|  |    don't want to use it!  */ | ||||||
| static void prim_tail(EvalState & state, Value * * args, Value & v) | static void prim_tail(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     state.forceList(*args[0]); |     state.forceList(*args[0]); | ||||||
|  | @ -930,6 +931,19 @@ static void prim_filter(EvalState & state, Value * * args, Value & v) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | static void prim_elem(EvalState & state, Value * * args, Value & v) | ||||||
|  | { | ||||||
|  |     bool res = false; | ||||||
|  |     state.forceList(*args[1]); | ||||||
|  |     for (unsigned int n = 0; n < args[1]->list.length; ++n) | ||||||
|  |         if (state.eqValues(*args[0], *args[1]->list.elems[n])) { | ||||||
|  |             res = true; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     mkBool(v, res); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /* Return the length of a list.  This is an O(1) time operation. */ | /* Return the length of a list.  This is an O(1) time operation. */ | ||||||
| static void prim_length(EvalState & state, Value * * args, Value & v) | static void prim_length(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|  | @ -1145,6 +1159,7 @@ void EvalState::createBaseEnv() | ||||||
|     addPrimOp("__tail", 1, prim_tail); |     addPrimOp("__tail", 1, prim_tail); | ||||||
|     addPrimOp("map", 2, prim_map); |     addPrimOp("map", 2, prim_map); | ||||||
|     addPrimOp("__filter", 2, prim_filter); |     addPrimOp("__filter", 2, prim_filter); | ||||||
|  |     addPrimOp("__elem", 2, prim_elem); | ||||||
|     addPrimOp("__length", 1, prim_length); |     addPrimOp("__length", 1, prim_length); | ||||||
| 
 | 
 | ||||||
|     // Integer arithmetic
 |     // Integer arithmetic
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue