On Monday, 31 March 2014 at 11:40:11 UTC, Steven Schveighoffer
wrote:
Blocking operations may have a noticeable impact, but they may
not. It depends on what you do between construction and
processing.
For example, if you have:
foreach(l; stdin.byLine)
Lazily fetching the first line makes no operational difference
whatsoever, even if it blocks, because you're immediately going
to process it.
But if it *is* lazily fetched, you are paying some possibly
small, but nonzero, cost for that laziness that you didn't need
to pay.
This is why I said it's not critically important to delay
unless you are not going to process the first element. Because
there is no primitive to "prime" the range, we must do it on a
property fetch, or on construction. But after that, popFront is
a perfectly reasonable place to get the next element.
All this fuss is over the *first* element in the range. I think
providing a mechanism to decide whether you want it now or
later is reasonable. For example a lazy range wrapper.
I've found the example I was talking about:
http://forum.dlang.org/thread/mailman.323.1393458346.6445.digitalmar...@puremagic.com
I misremembered, filter wasn't even involved. But similar
situations may arise from using filter or another range that
eagerly fetches the first element, even if its source doesn't.
Note, however, the case Andrei was arguing about was one of the
string decoders. When you are blocking for input, hell, even if
you aren't blocking, but need to call system calls to get it,
the performance cost of checking a boolean every call is
negligible. But when you are decoding 1-4 bytes of data in
memory, checking a boolean becomes significant.
That's what I meant by a tight loop. My hypothesis is that in
such cases the optimizers of at least GDC and LDC are good enough
to remove the check for the boolean completely, and that at least
LDC can then remove the boolean itself from the range structure.