Changeset 3375
- Timestamp:
- 12/24/05 01:10:24 (3 years ago)
- Files:
-
- Tuna/trunk/English.lproj/ReleaseNotes.rtf (modified) (2 diffs)
- Tuna/trunk/TNNode.h (modified) (1 diff)
- Tuna/trunk/TNNode.m (modified) (5 diffs)
- Tuna/trunk/TNParser.h (modified) (1 diff)
- Tuna/trunk/TNParser.m (modified) (7 diffs)
- Tuna/trunk/TNProfilerController.m (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
Tuna/trunk/English.lproj/ReleaseNotes.rtf
r2913 r3375 1 {\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf 1001 {\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf230 2 2 {\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;} 3 3 {\colortbl;\red255\green255\blue255;\red50\green100\blue255;\red227\green211\blue34;} … … 27 27 \cf2 1.0.1 28 28 \f1\b0 \cf0 \ 29 - Performance improvements for opening profiles\ 29 30 - Use proper "\'b5s" time unit\ 30 31 \ Tuna/trunk/TNNode.h
r2814 r3375 52 52 - (TNNode *)childAtIndex:(unsigned int)index; 53 53 - (TNNode *)lastChild; 54 - ( unsigned int)indexOfChildWithSub:(TNSub *)sub;54 - (TNNode *)childWithSub:(TNSub *)sub; 55 55 - (TNNode *)parent; 56 56 - (BOOL)isLeaf; Tuna/trunk/TNNode.m
r2814 r3375 41 41 42 42 43 44 43 @implementation TNNode 45 44 … … 168 167 #pragma mark - 169 168 170 - (void)addChild:(TNNode *) childNode {169 - (void)addChild:(TNNode *)node { 171 170 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 175 178 _leaf = NO; 176 179 } … … 196 199 197 200 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 } 206 214 } 207 215 208 return N SNotFound;216 return NULL; 209 217 } 210 218 … … 257 265 - (void)joinWithNode:(TNNode *)node { 258 266 TNNode *child; 259 unsigned int i, count , index;267 unsigned int i, count; 260 268 261 269 _calls++; … … 269 277 for(i = 0; i < count; i++) { 270 278 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 274 284 [self addChild:child]; 275 else276 [[_children objectAtIndex:index] joinWithNode:child];277 285 } 278 286 } Tuna/trunk/TNParser.h
r2814 r3375 32 32 NSString *_string; 33 33 34 NSMutableDictionary *_subs;35 NSMutableArray *_nodes;34 CFMutableArrayRef _nodes; 35 CFMutableDictionaryRef _subs; 36 36 37 37 NSArray *_colors; Tuna/trunk/TNParser.m
r2814 r3375 34 34 @interface TNParser(Private) 35 35 36 enum TNParserState {36 enum _TNParserState { 37 37 TNParserStateHeader, 38 38 TNParserStateData, 39 39 TNParserStateFinished, 40 40 }; 41 typedef enum TNParserState TNParserState;42 43 44 - (id) initWithString:(NSString *)string;45 46 - (TNTree *) parse;47 - (NSColor *) colorForPackage:(NSString *)package;41 typedef enum _TNParserState TNParserState; 42 43 44 - (id)_initWithString:(NSString *)string; 45 46 - (TNTree *)_parse; 47 - (NSColor *)_colorForPackage:(NSString *)package; 48 48 49 49 @end 50 50 51 51 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 { 68 55 self = [super init]; 69 56 70 57 _string = [string retain]; 71 58 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); 74 61 75 62 _usedColors = [[NSMutableDictionary alloc] initWithCapacity:50]; … … 95 82 96 83 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 112 84 #pragma mark - 113 85 114 - (TNTree *)parse { 115 NSString *line; 86 static 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; 116 111 TNTree *tree; 117 112 TNNode *node, *parentNode, *rootNode; 113 TNSub *sub; 118 114 TNParserState state; 119 NSRange range; 115 CFRange range, stringRange, bufferRange; 116 NSRange lineRange, fieldRange; 117 NSTimeInterval time; 118 unichar buffer[64]; 120 119 double secondsPerTick; 121 unsigned int offset, length; 122 120 unsigned int i, count, length, stime, utime, ticks; 121 122 time = [NSDate timeIntervalSinceReferenceDate]; 123 123 tree = [[TNTree alloc] init]; 124 124 rootNode = [tree rootNode]; 125 125 parentNode = rootNode; 126 126 state = TNParserStateHeader; 127 offset = 0;128 127 length = [_string length]; 128 stringRange = CFRangeMake(0, length); 129 129 secondsPerTick = 0.0; 130 130 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; 133 136 134 if( range.location == NSNotFound)135 break;137 if(lineRange.length == 0) 138 continue; 136 139 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 == '#') { 142 262 // --- comment 143 263 continue; 144 264 } 145 else if( [line hasPrefix:@"$"]) {265 else if(prefix == '$') { 146 266 NSScanner *scanner; 147 NSString * name, *value;267 NSString *line, *name, *value; 148 268 149 269 // --- variables in header 270 line = [_string substringWithRange:lineRange]; 150 271 scanner = [NSScanner scannerWithString:line]; 151 272 … … 169 290 } 170 291 } 171 else if([ lineisEqualToString:@"PART2"]) {292 else if([[_string substringWithRange:lineRange] isEqualToString:@"PART2"]) { 172 293 // --- get frequency 173 294 secondsPerTick = 1.0 / (double) [[tree->_variables objectForKey:@"hz"] floatValue]; 174 295 175 296 // --- beginning of data dump 176 297 state = TNParserStateData; … … 178 299 } 179 300 } 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 sub190 sub = [_subs objectForKey:line];191 192 if(!sub)193 continue;194 195 // --- add a node196 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 timing208 [_nodes addObject:node];209 210 // --- climb up211 parentNode = node;212 }213 else if(type == '-') {214 if([line characterAtIndex:2] != '&') {215 // --- climb down216 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 key229 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 package234 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 name239 name = [line substringWithRange:NSMakeRange(lineOffset, lineLength - lineOffset)];240 241 // --- add a sub242 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 timestamp260 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 }270 301 } 271 302 … … 273 304 [rootNode refreshPercent]; 274 305 306 NSLog(@"%.2fms", ([NSDate timeIntervalSinceReferenceDate] - time) * 1000.0); 307 275 308 return tree; 276 309 } … … 278 311 279 312 280 - (NSColor *) colorForPackage:(NSString *)package {313 - (NSColor *)_colorForPackage:(NSString *)package { 281 314 NSColor *color; 282 315 … … 296 329 297 330 @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 156 156 157 157 if(document) { 158 [document updateChangeCount:NSChangeDone]; 158 159 [document showWindows]; 159 160 [document retain];
