foreach vs static foreach on compile time tuples

Steven Schveighoffer schveiguy at gmail.com
Wed Aug 27 10:29:20 UTC 2025


On Tuesday, 26 August 2025 at 18:48:47 UTC, monkyyy wrote:
> ```d
> #!opend -unittest -main -run app.d
> bool isEvenImpl(int I)()=>! I%2;
> enum cases=10000;
> import std.range;
> bool isEven(int i){
> 	switch(i){
> 		static foreach(I;0..cases){
> 		//foreach(I;enumlist!(iota(cases))){
> 			case I: return isEvenImpl!I;
> 		}
> 		default: assert(0);
> }}
> template Val(int V){
> 	enum Val=V;
> }
> alias seq(T...)=T;
> template enumlist(alias R){
> 	alias enumlist=seq!();
> 	static foreach(e;R){
> 		enumlist=seq!(enumlist,Val!e);
> }}
> unittest{
> 	import std;
> 	alias A=enumlist!(iota(5));
> 	A.stringof.writeln;
> }
> unittest{
> 	import std;
> 	7.isEven.writeln;
> }
> ```
>
>> static foreach(I;0..cases){ //2.86s
>> foreach(I;enumlist!(iota(cases))){ //7.30s

Apples to oranges here.

Enumlist is a giant template with ctfe.

Static foreach vs foreach on the same ct sequence should be equal 
performance.

Note that biggest differences are that ct foreach can do break 
and continue, and only is valid in a function. As you point out 
in this post you can also do static foreach on a range.

The ct acrobatics that were necessary for ct foreach before 
static foreach existed I don’t want to return to.

-Steve


More information about the Digitalmars-d-learn mailing list