Re: Home-brewed code is 100X faster than -[NSScanner scanDecimal:] ??
Re: Home-brewed code is 100X faster than -[NSScanner scanDecimal:] ??
- Subject: Re: Home-brewed code is 100X faster than -[NSScanner scanDecimal:] ??
- From: Jerry Krinock <email@hidden>
- Date: Thu, 3 Feb 2011 13:05:25 -0800
Thanks, Glenn, and thanks, Matt, for the explanation.
So I added a parameter to my method which one can use to get the performance improvement only if they are willing to compromise accuracy and parsing of numbers written in "e" notation. Also, I chose a name which is less likely to used by Apple.
@interface NSScanner (BSSpeedy)
/*!
@brief Scans for a string representing a value, returning if found
value by reference, and offering an option to improve performance if
scanning of strings representing numbers in "e" notatation is not
required, and if double-precision accuracy is sufficient.
@details The performance improvement when using accurately:NO is typically
100x, and also autoreleased memory allocations are greatly reduced.
Invoke this method with NULL as number to simply scan past a string
representing a number.
@param number Upon return, contains the scanned value as either an
NSNumber or NSDecimalNumber value.
@param accurately If YES, the 'number' pointed to upon return will be
an NSDecimalNumber, and strings representing numbers in "e" notation
(i.e. a significand, followed by 'e' or 'E', followed by an exponent)
will be properly scanned.
If NO, the 'number' pointed to upon return will be an NSNumber whose value
will represent the input string only to double-precision value, and strings
representing numbers in "e" notation will not be scanned properly; the
significand and the exponent will be scanned as separate numbers.
@result YES if the receiver finds a string that it can scan to a number
value, otherwise NO.
*/
- (BOOL)scanBSNumber:(NSNumber**)number
accurately:(BOOL)accurately ;
@end
@implementation NSScanner (BSSpeedy)
- (BOOL)scanBSNumber:(NSNumber**)number
accurately:(BOOL)accurately {
NSString* string = nil ;
BOOL isDecimal ;
if (accurately) {
NSDecimal decimal ;
isDecimal = [self scanDecimal:&decimal];
if (isDecimal) {
*number = [NSDecimalNumber decimalNumberWithDecimal:decimal] ;
}
}
else {
NSCharacterSet* decimalSet ;
decimalSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789-."] ;
isDecimal = [self scanCharactersFromSet:decimalSet
intoString:&string] ;
if (isDecimal) {
double value ;
value = [string doubleValue] ; // See Note, below
*number = [NSNumber numberWithDouble:value] ;
}
}
return isDecimal ;
/*
Note. At first, I'd written a more complicated implementation which checked
if the number was an integer and if so used -numberWithInteger instead of
-numberWithDouble, but then found that performance of the current
implementation here is the same. I suppose this is because we've been
doing floating-point calculations in hardware for quite a few years now.
*/
}
@end
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden