AliasSeq seems to compile slightly faster with static foreach

Jonathan M Davis newsgroup.d at jmdavisprog.com
Sun Jan 7 23:21:28 UTC 2018


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



More information about the Digitalmars-d mailing list