On Sunday, January 07, 2018 09:59:30 Timon Gehr via Digitalmars-d wrote: > On 05.01.2018 14:10, Jonathan M Davis wrote: > > Taking it a step further, I tried switching some of the static foreach's > > over to using array literals, since they held values rather than types, > > and that seemed to have minimal impact on the time to run dub test. > > However, by switching to using std.range.only, it suddenly was taking > > more like 11.8 seconds. So, with a few small changes, I cut the time to > > run dub test down by almost a third. > > This is weird, as the compiler will apply the following rewrites: > > static foreach(i;only(0,1,2,3,4)){} > > => > > static foreach(i;{ > int[] r=[]; > foreach(i;only(0,1,2,3,4)){ > r~=i; > } > return r; > }()){} > > => // (using CTFE) > > static foreach(i;[0,1,2,3,4]){} > > => // (uses shortcut; not instantiating the AliasSeq template) > > static foreach(i;AliasSeq!(0,1,2,3,4)){}
I don't know. Looking at only's implementation, it uses a static array internally, not a dynamic one, so I would not have expected the lowering that you describe, but I don't know enough about the details of how the compiler works to know what it would really do - especially during CTFE - and I'd expect you to know far more about that than I would. Either way, with my project at least, with the unit tests that I was generating using foreach or static foreach, using static foreach with AliasSeq was slightly faster than using normal foreach, using array literals with static foreach was about the same as using AliasSeq with static foreach, and using only with static foreach was way faster than either - enough so that by switching all of my non-static foreach's over AliasSeqs of values to only (or lockstep with iota and only where I needed indices) resulted in dub test taking a bit over half as long as it did before. Now, I had a lot of unit tests using foreach with AliasSeqs of values, which is why the impact was so great in my case, but anecdotally, it implies that the compiler treats a static foreach over a std.range.only quite differently from one over an array literal or AliasSeq. - Jonathan M Davis