Using unsafe code for string->integer conversion, I must be doing something wrong...
I'm thinking that I must be doing something wrong. I've changed the code for converting Int16's over to using an unsafe method. In this method I'm precomputing the 1D array, just as I did before, I'm precomputing the fixed pointers (so the memory is locked into place, this might not be good), and it actually runs faster than previously written code. Anyway, here are the numbers:
TryParseInt16: 00:00:08.0215344
TryParseInt16_Elegance: 00:00:08.4821968
TryParseInt16_UseArray: 00:00:08.2718944
Here is the code I'm using. Since I'm not fixing the arrays in place, and I'm only fixing them once, I'm getting a small performance benefit. Fixing them in place would mean taking a fixed location, copying the pointer to some locals and then using that since we need to modify the pointer (pointers in fixed statements appear to be read-only until copied).
long* basedvalue = preMultiplied1DPointer;
ushort* validator = Int16MaxPointer;
while(parseBegin >= parseEnd) {
ushort accumulator = (ushort) (integer[parseBegin--] - '0');
if ( accumulator > *validator++ ) { return false; }
value += (short) *(basedvalue+accumulator);
basedvalue+=10;
}
This code is definitely more elegant. I like the validator fix, which basically looks like: { 9, 9, 9, 9, 3 }. That makes it quite a bit easier than having to either special case the last character, or unroll the loop. I called this TryInt16_Elegance, because I really think it looks better now. I just wish the speed was there, and I'm wondering now, why it isn't. As an aside, I'll also include the timings for when I use the fixed statements locally.
TryParseInt16: 00:00:07.9414192
TryParseInt16_Elegance: 00:00:09.2032336
The increase in the pinning takes a big hit, but not that big. Doing the ~33 million pins I guess doesn't affect the speed of the application that much. It only hurts us by about 1 second more or 12%.
DWC.Algorithms.NumberUtilities