Changeset 3375

Show
Ignore:
Timestamp:
12/24/05 01:10:24 (3 years ago)
Author:
morris
Message:

3.4 times performance boost on tmon load

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • Tuna/trunk/English.lproj/ReleaseNotes.rtf

    r2913 r3375  
    1 {\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf10
     1{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf23
    22{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;} 
    33{\colortbl;\red255\green255\blue255;\red50\green100\blue255;\red227\green211\blue34;} 
     
    2727\cf2 1.0.1 
    2828\f1\b0 \cf0 \ 
     29- Performance improvements for opening profiles\ 
    2930- Use proper "\'b5s" time unit\ 
    3031\ 
  • Tuna/trunk/TNNode.h

    r2814 r3375  
    5252- (TNNode *)childAtIndex:(unsigned int)index; 
    5353- (TNNode *)lastChild; 
    54 - (unsigned int)indexOfChildWithSub:(TNSub *)sub; 
     54- (TNNode *)childWithSub:(TNSub *)sub; 
    5555- (TNNode *)parent; 
    5656- (BOOL)isLeaf; 
  • Tuna/trunk/TNNode.m

    r2814 r3375  
    4141 
    4242 
    43  
    4443@implementation TNNode 
    4544 
     
    168167#pragma mark - 
    169168 
    170 - (void)addChild:(TNNode *)childNode { 
     169- (void)addChild:(TNNode *)node { 
    171170        if(!_children) 
    172                 _children = [[NSMutableArray alloc] initWithCapacity:100]; 
    173  
    174         [_children addObject:childNode]; 
     171                _children = (id) CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); 
     172                 
     173        CFArrayReplaceValues((CFMutableArrayRef) _children, 
     174                                                 CFRangeMake(CFArrayGetCount((CFMutableArrayRef) _children), 0), 
     175                                                 (void *) &node, 
     176                                                 1); 
     177         
    175178        _leaf = NO; 
    176179} 
     
    196199 
    197200 
    198 - (unsigned int)indexOfChildWithSub:(TNSub *)sub { 
    199         unsigned int    i, count; 
    200          
    201         count = [_children count]; 
    202          
    203         for(i = 0; i < count; i++) { 
    204                 if(((TNNode *) [_children objectAtIndex:i])->_sub == sub) 
    205                         return i; 
     201- (TNNode *)childWithSub:(TNSub *)sub { 
     202        TNNode                  *node; 
     203        unsigned int    i, count; 
     204         
     205        if(_children) { 
     206                count = CFArrayGetCount((CFMutableArrayRef) _children); 
     207                 
     208                for(i = 0; i < count; i++) { 
     209                        node = (id) CFArrayGetValueAtIndex((CFMutableArrayRef) _children, i); 
     210                         
     211                        if(node->_sub == sub) 
     212                                return node; 
     213                } 
    206214        } 
    207215         
    208         return NSNotFound
     216        return NULL
    209217} 
    210218 
     
    257265- (void)joinWithNode:(TNNode *)node { 
    258266        TNNode                  *child; 
    259         unsigned int    i, count, index
     267        unsigned int    i, count
    260268 
    261269        _calls++; 
     
    269277        for(i = 0; i < count; i++) { 
    270278                child = [node->_children objectAtIndex:i]; 
    271                 index = [self indexOfChildWithSub:child->_sub]; 
    272  
    273                 if(index == NSNotFound) 
     279                node = [self childWithSub:child->_sub]; 
     280                 
     281                if(node) 
     282                        [node joinWithNode:child]; 
     283                else 
    274284                        [self addChild:child]; 
    275                 else 
    276                         [[_children objectAtIndex:index] joinWithNode:child]; 
    277285        } 
    278286} 
  • Tuna/trunk/TNParser.h

    r2814 r3375  
    3232        NSString                                        *_string; 
    3333 
    34         NSMutableDictionary                    *_subs; 
    35         NSMutableArray                         *_nodes; 
     34        CFMutableArrayRef                      _nodes; 
     35        CFMutableDictionaryRef         _subs; 
    3636         
    3737        NSArray                                         *_colors; 
  • Tuna/trunk/TNParser.m

    r2814 r3375  
    3434@interface TNParser(Private) 
    3535 
    36 enum TNParserState { 
     36enum _TNParserState { 
    3737        TNParserStateHeader, 
    3838        TNParserStateData, 
    3939        TNParserStateFinished, 
    4040}; 
    41 typedef enum TNParserState            TNParserState; 
    42  
    43  
    44 - (id)initWithString:(NSString *)string; 
    45  
    46 - (TNTree *)parse; 
    47 - (NSColor *)colorForPackage:(NSString *)package; 
     41typedef enum _TNParserState           TNParserState; 
     42 
     43 
     44- (id)_initWithString:(NSString *)string; 
     45 
     46- (TNTree *)_parse; 
     47- (NSColor *)_colorForPackage:(NSString *)package; 
    4848 
    4949@end 
    5050 
    5151 
    52  
    53 @implementation TNParser 
    54  
    55 + (TNTree *)parseWithString:(NSString *)string { 
    56         TNParser        *parser; 
    57          
    58         parser = [[[self alloc] initWithString:string] autorelease]; 
    59  
    60         return [parser parse]; 
    61 
    62  
    63  
    64  
    65 #pragma mark - 
    66  
    67 - (id)initWithString:(NSString *)string { 
     52@implementation TNParser(Private) 
     53 
     54- (id)_initWithString:(NSString *)string { 
    6855        self = [super init]; 
    6956         
    7057        _string         = [string retain]; 
    7158 
    72         _subs          = [[NSMutableDictionary alloc] initWithCapacity:1000]
    73         _nodes         = [[NSMutableArray alloc] initWithCapacity:500]
     59        _nodes         = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks)
     60        _subs          = CFDictionaryCreateMutable(NULL, 0, NULL, &kCFTypeDictionaryValueCallBacks)
    7461 
    7562        _usedColors     = [[NSMutableDictionary alloc] initWithCapacity:50]; 
     
    9582 
    9683 
    97 - (void)dealloc { 
    98         [_string release]; 
    99          
    100         [_subs release]; 
    101         [_nodes release]; 
    102          
    103         [_usedColors release]; 
    104          
    105         [_colors release]; 
    106          
    107         [super dealloc]; 
    108 } 
    109  
    110  
    111  
    11284#pragma mark - 
    11385 
    114 - (TNTree *)parse { 
    115         NSString                *line; 
     86static inline unsigned int _TNHash(const unichar *buffer, unsigned int length) { 
     87        unsigned int            hash; 
     88        const unichar           *end, *end4; 
     89         
     90        hash    = length; 
     91        end             = buffer + length; 
     92        end4    = buffer + (length & ~3); 
     93 
     94        while(buffer < end4) { 
     95                hash = hash * 67503105 + buffer[0] * 16974593 + buffer[1] * 66049 + buffer[2] * 257 + buffer[3]; 
     96                buffer += 4; 
     97        } 
     98 
     99        while(buffer < end) 
     100                hash = hash * 257 + *buffer++; 
     101         
     102        return hash + (hash << (length & 31)); 
     103
     104 
     105 
     106 
     107#pragma mark - 
     108 
     109- (TNTree *)_parse { 
     110        NSString                *key, *package, *name; 
    116111        TNTree                  *tree; 
    117112        TNNode                  *node, *parentNode, *rootNode; 
     113        TNSub                   *sub; 
    118114        TNParserState   state; 
    119         NSRange                 range; 
     115        CFRange                 range, stringRange, bufferRange; 
     116        NSRange                 lineRange, fieldRange; 
     117        NSTimeInterval  time; 
     118        unichar                 buffer[64]; 
    120119        double                  secondsPerTick; 
    121         unsigned int    offset, length; 
    122          
     120        unsigned int    i, count, length, stime, utime, ticks; 
     121         
     122        time                    = [NSDate timeIntervalSinceReferenceDate]; 
    123123        tree                    = [[TNTree alloc] init]; 
    124124        rootNode                = [tree rootNode]; 
    125125        parentNode              = rootNode; 
    126126        state                   = TNParserStateHeader; 
    127         offset                  = 0; 
    128127        length                  = [_string length]; 
     128        stringRange             = CFRangeMake(0, length); 
    129129        secondsPerTick  = 0.0; 
    130130         
    131         while(YES) { 
    132                 range = [_string rangeOfString:@"\n" options:0 range:NSMakeRange(offset, length - offset)]; 
     131        while(CFStringFindWithOptions((CFStringRef) _string, (CFStringRef) @"\n", stringRange, 0, &range)) { 
     132                lineRange.location              = stringRange.location; 
     133                lineRange.length                = range.location - lineRange.location; 
     134                stringRange.location    = range.location + 1; 
     135                stringRange.length              = length - stringRange.location; 
    133136                 
    134                 if(range.location == NSNotFound
    135                         break
     137                if(lineRange.length == 0
     138                        continue
    136139                 
    137                 line = [_string substringWithRange:NSMakeRange(offset, range.location - offset)]; 
    138                 offset = range.location + 1; 
    139                  
    140                 if(state == TNParserStateHeader) { 
    141                         if([line hasPrefix:@"#"]) { 
     140                if(state == TNParserStateData) { 
     141                        unichar         type; 
     142         
     143                        type = CFStringGetCharacterAtIndex((CFStringRef) _string, lineRange.location); 
     144                         
     145                        switch(type) { 
     146                                case '+': 
     147                                        if(lineRange.length >= 8 && CFStringGetCharacterAtIndex((CFStringRef) _string, lineRange.location + 2) == '&') 
     148                                                continue; 
     149 
     150                                        // --- retrieve previously saved sub 
     151                                        bufferRange.location = lineRange.location + 2; 
     152                                        bufferRange.length = lineRange.length - 2; 
     153                                         
     154                                        CFStringGetCharacters((CFStringRef) _string, bufferRange, buffer); 
     155 
     156                                        sub = (id) CFDictionaryGetValue(_subs, (void *) _TNHash(buffer, bufferRange.length)); 
     157 
     158                                        if(sub) { 
     159                                                // --- add a node 
     160                                                node = [parentNode childWithSub:sub]; 
     161                                                 
     162                                                if(node) { 
     163                                                        node->_calls++; 
     164                                                } else { 
     165                                                        node = [[TNNode allocWithZone:NULL] initWithParent:parentNode sub:sub]; 
     166                                                        [parentNode addChild:node]; 
     167                                                        [node release]; 
     168                                                } 
     169                                                 
     170                                                // --- add for timing 
     171                                                bufferRange.location = CFArrayGetCount(_nodes); 
     172                                                bufferRange.length = 0; 
     173                                                 
     174                                                CFArrayReplaceValues(_nodes, bufferRange, (void *) &node, 1); 
     175 
     176                                                // --- climb up 
     177                                                parentNode = node; 
     178                                        } 
     179                                        break; 
     180                                 
     181                                case '-': 
     182                                        if(lineRange.length >= 8 && CFStringGetCharacterAtIndex((CFStringRef) _string, lineRange.location + 2) == '&') 
     183                                                continue; 
     184 
     185                                        // --- climb down 
     186                                        parentNode = parentNode->_parent; 
     187                                        break; 
     188                                 
     189                                case '&': 
     190                                        // --- extract key 
     191                                        i                       = 2; 
     192                                        fieldRange      = [_string rangeOfString:@" " 
     193                                                                                                 options:NSLiteralSearch 
     194                                                                                                   range:NSMakeRange(lineRange.location + i, lineRange.length - i)]; 
     195                                        fieldRange      = NSMakeRange(lineRange.location + i, fieldRange.location - lineRange.location - i); 
     196                                        key                     = [_string substringWithRange:fieldRange]; 
     197                                         
     198                                        // --- extract package 
     199                                        i                       = fieldRange.location + fieldRange.length - lineRange.location + 1; 
     200                                        fieldRange      = [_string rangeOfString:@" " 
     201                                                                                                 options:NSLiteralSearch 
     202                                                                                                   range:NSMakeRange(lineRange.location + i, lineRange.length - i)]; 
     203                                        fieldRange      = NSMakeRange(lineRange.location + i, fieldRange.location - lineRange.location - i); 
     204                                        package         = [_string substringWithRange:fieldRange]; 
     205                                         
     206                                        // --- extract name 
     207                                        i                       = fieldRange.location + fieldRange.length - lineRange.location + 1; 
     208                                        fieldRange      = NSMakeRange(lineRange.location + i, lineRange.length - i); 
     209                                        name            = [_string substringWithRange:fieldRange]; 
     210                                         
     211                                        // --- add a sub 
     212                                        sub = [[TNSub alloc] initWithPackage:package name:name color:[self _colorForPackage:package]]; 
     213                                        CFStringGetCharacters((CFStringRef) key, CFRangeMake(0, [key length]), buffer); 
     214                                        CFDictionaryAddValue(_subs, (void *) _TNHash(buffer, [key length]), sub); 
     215                                        [sub release]; 
     216                                        break; 
     217                                         
     218                                case '@': 
     219                                        count = CFArrayGetCount(_nodes); 
     220                                         
     221                                        if(count > 0) { 
     222                                                // --- extract user time 
     223                                                i                       = 2; 
     224                                                fieldRange      = [_string rangeOfString:@" " 
     225                                                                                                         options:NSLiteralSearch 
     226                                                                                                           range:NSMakeRange(lineRange.location + i, lineRange.length - i)]; 
     227                                                fieldRange      = NSMakeRange(lineRange.location + i, fieldRange.location - lineRange.location - i); 
     228                                                utime           = [[_string substringWithRange:fieldRange] unsignedIntValue]; 
     229                                                 
     230                                                // --- extract system time 
     231                                                i                       = fieldRange.location + fieldRange.length - lineRange.location + 1; 
     232                                                fieldRange      = [_string rangeOfString:@" " 
     233                                                                                                         options:NSLiteralSearch 
     234                                                                                                           range:NSMakeRange(lineRange.location + i, lineRange.length - i)]; 
     235                                                fieldRange      = NSMakeRange(lineRange.location + i, fieldRange.location - lineRange.location - i); 
     236                                                stime           = [[_string substringWithRange:fieldRange] unsignedIntValue]; 
     237                                                 
     238                                                // --- we only consider total time 
     239                                                ticks           = utime + stime; 
     240                                                 
     241                                                if(ticks > 0) { 
     242                                                        double          time; 
     243                                                         
     244                                                        // --- add time for all nodes since last timestamp 
     245                                                        time = (ticks * secondsPerTick) / count; 
     246                                                         
     247                                                        for(i = 0; i < count; i++) 
     248                                                                [(id) CFArrayGetValueAtIndex(_nodes, i) addTime:time]; 
     249                                                         
     250                                                        CFArrayRemoveAllValues(_nodes); 
     251                                                } 
     252                                        } 
     253                                        break; 
     254                        } 
     255                } 
     256                else if(state == TNParserStateHeader) { 
     257                        unichar         prefix; 
     258                         
     259                        prefix = [_string characterAtIndex:lineRange.location]; 
     260                         
     261                        if(prefix == '#') { 
    142262                                // --- comment 
    143263                                continue; 
    144264                        } 
    145                         else if([line hasPrefix:@"$"]) { 
     265                        else if(prefix == '$') { 
    146266                                NSScanner       *scanner; 
    147                                 NSString        *name, *value; 
     267                                NSString        *line, *name, *value; 
    148268                                 
    149269                                // --- variables in header 
     270                                line = [_string substringWithRange:lineRange]; 
    150271                                scanner = [NSScanner scannerWithString:line]; 
    151272                                 
     
    169290                                } 
    170291                        } 
    171                         else if([line isEqualToString:@"PART2"]) { 
     292                        else if([[_string substringWithRange:lineRange] isEqualToString:@"PART2"]) { 
    172293                                // --- get frequency 
    173294                                secondsPerTick = 1.0 / (double) [[tree->_variables objectForKey:@"hz"] floatValue]; 
    174  
     295                                 
    175296                                // --- beginning of data dump 
    176297                                state = TNParserStateData; 
     
    178299                        } 
    179300                } 
    180                 else if(state == TNParserStateData && [line length] > 0) { 
    181                         unichar         type; 
    182                          
    183                         type = [line characterAtIndex:0]; 
    184                          
    185                         if(type == '+' || type == '*') { 
    186                                 TNSub                   *sub; 
    187                                 unsigned int    index; 
    188                  
    189                                 // --- retrieve previously saved sub 
    190                                 sub = [_subs objectForKey:line]; 
    191                                  
    192                                 if(!sub) 
    193                                         continue; 
    194                                  
    195                                 // --- add a node 
    196                                 index = [parentNode indexOfChildWithSub:sub]; 
    197                                  
    198                                 if(index == NSNotFound) { 
    199                                         node = [[TNNode alloc] initWithParent:parentNode sub:sub]; 
    200                                         [parentNode addChild:node]; 
    201                                         [node release]; 
    202                                 } else { 
    203                                         node = [parentNode->_children objectAtIndex:index]; 
    204                                         node->_calls++; 
    205                                 } 
    206                                  
    207                                 // --- add for timing 
    208                                 [_nodes addObject:node]; 
    209  
    210                                 // --- climb up 
    211                                 parentNode = node; 
    212                         } 
    213                         else if(type == '-') { 
    214                                 if([line characterAtIndex:2] != '&') { 
    215                                         // --- climb down 
    216                                         parentNode = parentNode->_parent; 
    217                                 } 
    218                         } 
    219                         else if(type == '&') { 
    220                                 NSString                *key, *package, *name; 
    221                                 TNSub                   *sub; 
    222                                 NSRange                 range; 
    223                                 unsigned int    lineLength, lineOffset; 
    224                                  
    225                                 lineLength = [line length]; 
    226                                 lineOffset = 2; 
    227  
    228                                 // --- extract key 
    229                                 range           = [line rangeOfString:@" " options:0 range:NSMakeRange(lineOffset, lineLength - lineOffset)]; 
    230                                 key                     = [line substringWithRange:NSMakeRange(lineOffset, range.location - lineOffset)]; 
    231                                 lineOffset      = range.location + 1; 
    232  
    233                                 // --- extract package 
    234                                 range           = [line rangeOfString:@" " options:0 range:NSMakeRange(lineOffset, lineLength - lineOffset)]; 
    235                                 package         = [line substringWithRange:NSMakeRange(lineOffset, range.location - lineOffset)]; 
    236                                 lineOffset      = range.location + 1; 
    237                                  
    238                                 // --- extract name 
    239                                 name            = [line substringWithRange:NSMakeRange(lineOffset, lineLength - lineOffset)]; 
    240  
    241                                 // --- add a sub 
    242                                 sub = [[TNSub alloc] initWithPackage:package name:name color:[self colorForPackage:package]]; 
    243                                 [_subs setObject:sub forKey:[@"+ " stringByAppendingString:key]]; 
    244                                 [sub release]; 
    245                         } 
    246                         else if(type == '@') { 
    247                                 unsigned int    i, count, stime, utime, ticks; 
    248                                  
    249                                 count = [_nodes count]; 
    250                                  
    251                                 if(count > 0) { 
    252                                         utime = [[line substringWithRange:NSMakeRange(2, 1)] intValue]; 
    253                                         stime = [[line substringWithRange:NSMakeRange(4, 1)] intValue]; 
    254                                         ticks = utime + stime; 
    255                                          
    256                                         if(ticks > 0) { 
    257                                                 double          time; 
    258                                                  
    259                                                 // --- add time for all nodes since last timestamp 
    260                                                 time = (ticks * secondsPerTick) / count; 
    261                                                  
    262                                                 for(i = 0; i < count; i++) 
    263                                                         [[_nodes objectAtIndex:i] addTime:time]; 
    264  
    265                                                 [_nodes removeAllObjects]; 
    266                                         } 
    267                                 } 
    268                         } 
    269                 } 
    270301        } 
    271302         
     
    273304        [rootNode refreshPercent]; 
    274305         
     306        NSLog(@"%.2fms", ([NSDate timeIntervalSinceReferenceDate] - time) * 1000.0); 
     307 
    275308        return tree; 
    276309} 
     
    278311 
    279312 
    280 - (NSColor *)colorForPackage:(NSString *)package { 
     313- (NSColor *)_colorForPackage:(NSString *)package { 
    281314        NSColor         *color; 
    282315         
     
    296329 
    297330@end 
     331 
     332 
     333 
     334@implementation TNParser 
     335 
     336+ (TNTree *)parseWithString:(NSString *)string { 
     337        TNParser        *parser; 
     338         
     339        parser = [[[self alloc] _initWithString:string] autorelease]; 
     340 
     341        return [parser _parse]; 
     342} 
     343 
     344 
     345 
     346#pragma mark - 
     347 
     348- (void)dealloc { 
     349        [_string release]; 
     350         
     351        CFRelease(_nodes); 
     352        CFRelease(_subs); 
     353         
     354        [_usedColors release]; 
     355         
     356        [_colors release]; 
     357         
     358        [super dealloc]; 
     359} 
     360 
     361@end 
  • Tuna/trunk/TNProfilerController.m

    r2814 r3375  
    156156         
    157157        if(document) { 
     158                [document updateChangeCount:NSChangeDone]; 
    158159                [document showWindows]; 
    159160                [document retain];