class templates and static if
Dmitry Olshansky
dmitry.olsh at gmail.com
Mon Feb 27 11:55:39 PST 2012
On 27.02.2012 23:18, Jonathan M Davis wrote:
> On Monday, February 27, 2012 10:55:12 Ali Çehreli wrote:
>> On 02/27/2012 08:29 AM, Tyler Jameson Little wrote:
>>> I didn't want to do subclassing, because my parser is a state-machine
>>
>> style
>>
>>> parser, so it's in a big switch. Pretty gross, but I would like it to
>>
>> be as
>>
>>> fast as possible. That's why I thought this model would be so cool,
>>
>> because
>>
>>> I could remove conditions from the generated code, and get rid of a
>>
>> lot of
>>
>>> the conditionals.
>>
>> I am pretty sure switch statements boil down to a sequence conditionals
>> consisting of equality comparisons.
>>
>> I know that some compilers use optimizations where the comparisons are
>> converted to a single lookup, but last I checked, dmd does not apply
>> that optimization. Perhaps because it's not implemented yet, or because
>> using a table lookup might be slower because of reaching outside of the
>> cpu cache. (Or another reason that I am not aware of. :))
>
> Yeah. In theory, switch statements can be optimized better than if-else
> chains, and eventually I'd fully expect that dmd would do that, but right now,
> I don't think that they really are. You'd have to look at the generated
> assembly though to be sure though.
Please stop spreading the misconception that they are going to be
optimized "probably and eventually". Switch statements over integers are
much better then if/else chains and were for something like 20 years.
They do produce nice improvements over a sequence of if/else because
values are known in advance and are bounded.
So it goes like this:
1. If all numbers are tightly packed (e.g. almost all of M..N range is
covered by a case) then it does a jump table. So there is almost no
comparisons at all (just check it fits the range) and it's just one
indirect jump.
2.Even failing that it does a binary-search like comparisons to speed
thing up.
3. Sometimes linear searching is faster then binary (on small number of
case) and it can estimate this threshold. Same goes for table vs linear
search and table vs binary search.
4. In fact it even does combination of all of the above, e.g. separate
range in two by one comparison then use jump tables in both etc.
For instance:
switch(x){
case 0:
...
case 1:
...
case 4:
...
case 9:
... //all cases used up to 40
case 40:
It might do something like (depends on compiler vendor ;) ):
if( x < 9)
{
if(x == 0)
...
else if(x == 1)
...
else if(x == 4)
...
}
else {
if(x <=40)
goto table[x]; //pseudocode
else
goto default;
}
And for the record I seen all of that in assembly listings produced by
dmd, when optimizing VM dispatch in std.regex. I had to revisit opcodes
layout a bit so that dmd outputs jump table and not a binary-searching
like stuff in a tight loop.
--
Dmitry Olshansky
More information about the Digitalmars-d-learn
mailing list