Mirsad Todorovac wrote:
You might think that the function is very optimized, since it requires only two comparisons and a lookup in table per character checked?
Alas, GPC does a proper call to the real memcpy() function of complete ``v'' array on each call of function DigitValue() !!!
Normal local variables are (by definition!) created each time the routine is called. To avoid this, give them the `static' attribute (non-standard), or declare them as `const' (non-standard, BP). The latter is obviously preferrable since the array is really constant.
BTW, since you only access the array in the range '0' .. 'z', you only need to declare this part and can omit the lots of `-1' entries. Also, char indices are perfectly alright, so you don't have to use `Ord' here.
Just FYI, making ``v'' array [0..255] of Integer (for aligned access) made it even 10s slower (probably problems with FSB and cache), instead of what is commonly said,
Probably because of the initialization (see above) which takes 4 or 8 times as long then, of course (and which takes most time at all).
and complete code is not a bit faster from this variant:
function DigitValue (Dig: Char): Integer; attribute (inline, const); var d : Integer; attribute (register); begin if (Dig >= '0') and (Dig <= '9' ) then DigitValue := Ord (Dig) - Ord ('0') else if (Dig >= 'a') and (Dig <= 'z') then DigitValue := Ord (Dig) - Ord ('a') + 10 else if (Dig >= 'A') and (Dig <= 'Z') then DigitValue := Ord (Dig) - Ord ('A') + 10 else DigitValue := -1 end;
... even though this code has six branches.
Only 3 branches (the backend optimized better than you think -- unfortunately in this case only with `{$B+}', since Boolean shortcuts require special handling) which makes the array above look rather questionable ...
Frank