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 (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to