Proposal for SentinelInputRange

monarch_dodra monarchdodra at gmail.com
Thu Feb 28 07:31:42 PST 2013


On Thursday, 28 February 2013 at 14:31:08 UTC, Steven 
Schveighoffer wrote:
> On Thu, 28 Feb 2013 06:23:45 -0500, deadalnix
>
> I have to say I agree with deadalnix.
>
> you have essentially in lexer.c:
>
> outer:
> while(1)
> {
>    switch(r.front)
>    {
>       case 0:
>         break outer;
>       ...
>    }
> }
>
> whereas a range where empty is defined as r.front == 0:
>
> while(!r.empty)  // inlined to r.front != 0
> {
>    switch(r.front) // why would another load occur here?
>    {
>       // no need to check for 0, already done
>       ...
>    }
> }
>
> If this doesn't translate to the same code, I don't know why 
> not[SNIP].
>
> -Steve

The difference is that by doing "!r.empty" first, you are 
actually executing "r.front == 0" each and every time, before 
doing the rest of the checks proper.

Doing it the other way around however, the only time you actually 
check the sentinel value is once you've reached the actual 
sentinel value, or you've run out of values "of interest": EG not 
actually on every element.

You are basically re-ordering the tests to speed up the usual 
case.

//----

This is kind of the same logic as in C++'s "operator=": It is 
recommended to always check for self assignment. However, most 
quality implementations will *not* execute this check, instead 
being extra careful about instruction ordering.

While the rare self-assignement case becomes more expensive, the 
common assignment becomes cheaper. That's where the win is.


More information about the Digitalmars-d mailing list