From e570c3e50a4363bcf5761e59176af930403b8f11 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Mon, 24 Nov 2008 02:14:53 +0100 Subject: [PATCH] Use structs for graph lines We used to use NSObjects, which was really expensive, because for each commit as many as 100 graphlines can be created. By preallocating them and not using NSObjects in general, we gain a massive speedup --- GitX.xcodeproj/project.pbxproj | 6 ------ PBGitGraphLine.h | 21 ++++++-------------- PBGitGraphLine.m | 1 - PBGitGrapher.mm | 35 ++++++++++++++++++++++++---------- PBGitRevisionCell.m | 10 ++++++---- PBGraphCellInfo.h | 12 ++++++++---- PBGraphCellInfo.m | 11 +++++++++-- 7 files changed, 54 insertions(+), 42 deletions(-) diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj index 1c385375b..6c69511c0 100644 --- a/GitX.xcodeproj/project.pbxproj +++ b/GitX.xcodeproj/project.pbxproj @@ -46,7 +46,6 @@ F565262B0E03D89B00F03B52 /* PBWebHistoryController.m in Sources */ = {isa = PBXBuildFile; fileRef = F565262A0E03D89B00F03B52 /* PBWebHistoryController.m */; }; F56ADDD90ED19F9E002AC78F /* AddBranchTemplate.png in Resources */ = {isa = PBXBuildFile; fileRef = F56ADDD70ED19F9E002AC78F /* AddBranchTemplate.png */; }; F56ADDDA0ED19F9E002AC78F /* AddLabelTemplate.png in Resources */ = {isa = PBXBuildFile; fileRef = F56ADDD80ED19F9E002AC78F /* AddLabelTemplate.png */; }; - F56CC7290E65E0AD004307B4 /* PBGitGraphLine.m in Sources */ = {isa = PBXBuildFile; fileRef = F56CC7280E65E0AD004307B4 /* PBGitGraphLine.m */; }; F56CC7320E65E0E5004307B4 /* PBGraphCellInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = F56CC7310E65E0E5004307B4 /* PBGraphCellInfo.m */; }; F57240BB0E9678EA00D8EE66 /* deleted_file.png in Resources */ = {isa = PBXBuildFile; fileRef = F57240BA0E9678EA00D8EE66 /* deleted_file.png */; }; F574A2850EAE2EAC003F2CB1 /* PBRefController.m in Sources */ = {isa = PBXBuildFile; fileRef = F574A2840EAE2EAC003F2CB1 /* PBRefController.m */; }; @@ -65,7 +64,6 @@ F5886A1E0ED5D3880066E74C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; F5886A260ED5D4870066E74C /* PBGitGrapher.mm in Sources */ = {isa = PBXBuildFile; fileRef = F5FF4E790E082E440006317A /* PBGitGrapher.mm */; }; F5886A270ED5D4870066E74C /* PBGitRevisionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F50FE0E20E07BE9600854FCD /* PBGitRevisionCell.m */; }; - F5886A280ED5D4870066E74C /* PBGitGraphLine.m in Sources */ = {isa = PBXBuildFile; fileRef = F56CC7280E65E0AD004307B4 /* PBGitGraphLine.m */; }; F5886A290ED5D4870066E74C /* PBGraphCellInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = F56CC7310E65E0E5004307B4 /* PBGraphCellInfo.m */; }; F5886A2A0ED5D4870066E74C /* PBGitLane.mm in Sources */ = {isa = PBXBuildFile; fileRef = F5C6F68C0E65FF9300478D97 /* PBGitLane.mm */; }; F5886A310ED5D54C0066E74C /* PBGitConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 93FCCBA80EA8AF450061B02B /* PBGitConfig.m */; }; @@ -190,7 +188,6 @@ F56ADDD70ED19F9E002AC78F /* AddBranchTemplate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = AddBranchTemplate.png; path = Images/AddBranchTemplate.png; sourceTree = ""; }; F56ADDD80ED19F9E002AC78F /* AddLabelTemplate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = AddLabelTemplate.png; path = Images/AddLabelTemplate.png; sourceTree = ""; }; F56CC7270E65E0AD004307B4 /* PBGitGraphLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitGraphLine.h; sourceTree = ""; }; - F56CC7280E65E0AD004307B4 /* PBGitGraphLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitGraphLine.m; sourceTree = ""; }; F56CC7300E65E0E5004307B4 /* PBGraphCellInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGraphCellInfo.h; sourceTree = ""; }; F56CC7310E65E0E5004307B4 /* PBGraphCellInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGraphCellInfo.m; sourceTree = ""; }; F57240BA0E9678EA00D8EE66 /* deleted_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = deleted_file.png; path = Images/deleted_file.png; sourceTree = ""; }; @@ -506,7 +503,6 @@ F50FE0E10E07BE9600854FCD /* PBGitRevisionCell.h */, F50FE0E20E07BE9600854FCD /* PBGitRevisionCell.m */, F56CC7270E65E0AD004307B4 /* PBGitGraphLine.h */, - F56CC7280E65E0AD004307B4 /* PBGitGraphLine.m */, F56CC7300E65E0E5004307B4 /* PBGraphCellInfo.h */, F56CC7310E65E0E5004307B4 /* PBGraphCellInfo.m */, F5C6F68B0E65FF9300478D97 /* PBGitLane.h */, @@ -745,7 +741,6 @@ F5FF4E7A0E082E440006317A /* PBGitGrapher.mm in Sources */, 911111F80E594F3F00BF76B4 /* PBRepositoryDocumentController.m in Sources */, 913D5E5F0E556A9300CECEA2 /* PBCLIProxy.mm in Sources */, - F56CC7290E65E0AD004307B4 /* PBGitGraphLine.m in Sources */, F56CC7320E65E0E5004307B4 /* PBGraphCellInfo.m in Sources */, F5C6F68D0E65FF9300478D97 /* PBGitLane.mm in Sources */, F5C007750E731B48007B84B2 /* PBGitRef.m in Sources */, @@ -795,7 +790,6 @@ F5886A270ED5D4870066E74C /* PBGitRevisionCell.m in Sources */, F5886A320ED5D5510066E74C /* PBGitCommit.m in Sources */, F5886A340ED5D55D0066E74C /* PBGitBinary.m in Sources */, - F5886A280ED5D4870066E74C /* PBGitGraphLine.m in Sources */, F5886A290ED5D4870066E74C /* PBGraphCellInfo.m in Sources */, F5886A2A0ED5D4870066E74C /* PBGitLane.mm in Sources */, F5886A1B0ED5D37C0066E74C /* NSFileHandleExt.m in Sources */, diff --git a/PBGitGraphLine.h b/PBGitGraphLine.h index 5ff7806b0..fde931072 100644 --- a/PBGitGraphLine.h +++ b/PBGitGraphLine.h @@ -6,19 +6,10 @@ // Copyright 2008 __MyCompanyName__. All rights reserved. // -#import - - -@interface PBGitGraphLine : NSObject +struct PBGitGraphLine { - char upper; - char from; - char to; - char colorIndex; -} -@property(readonly) char upper, from, to, colorIndex; -- (id)initWithUpper: (char) u From: (char) f to: (char) t color: (char) c; -+ (PBGitGraphLine*) lowerLineFrom:(char) f to: (char) t color: (char) c; -+ (PBGitGraphLine*) upperLineFrom:(char) f to: (char) t color: (char) c; - -@end \ No newline at end of file + int upper : 1; + int from : 8; + int to : 8; + int colorIndex : 8; +}; diff --git a/PBGitGraphLine.m b/PBGitGraphLine.m index 6435e965a..b4a36e7bc 100644 --- a/PBGitGraphLine.m +++ b/PBGitGraphLine.m @@ -8,7 +8,6 @@ #import "PBGitGraphLine.h" - @implementation PBGitGraphLine @synthesize upper, from, to, colorIndex; - (id)initWithUpper: (char) u From: (char) f to: (char) t color: (char) c; diff --git a/PBGitGrapher.mm b/PBGitGrapher.mm index 5eecc968d..8344e3b57 100644 --- a/PBGitGrapher.mm +++ b/PBGitGrapher.mm @@ -13,6 +13,7 @@ #import "PBGitGrapher.h" #import "PBGitCommit.h" #import "PBGitLane.h" +#import "PBGitGraphLine.h" #import using namespace std; @@ -33,13 +34,23 @@ - (id) initWithRepository: (PBGitRepository*) repo return self; } +void add_line(struct PBGitGraphLine *lines, int *nLines, int upper, int from, int to, int index) +{ + // TODO: put in one thing + struct PBGitGraphLine a = { upper, from, to, index }; + lines[(*nLines)++] = a; +} + - (void) decorateCommit: (PBGitCommit *) commit { int i = 0, newPos = -1; std::vector *currentLanes = new std::vector; std::vector *previousLanes = (std::vector *)pl; - NSMutableArray* lines = [NSMutableArray array]; + int maxLines = (previousLanes->size() + [commit.parents count] + 2) * 3; + struct PBGitGraphLine *lines = (struct PBGitGraphLine *)malloc(sizeof(struct PBGitGraphLine) * maxLines); + int currentLine = 0; + PBGitLane *currentLane = NULL; BOOL didFirst = NO; @@ -57,26 +68,26 @@ - (void) decorateCommit: (PBGitCommit *) commit currentLanes->push_back(*it); currentLane = currentLanes->back(); newPos = currentLanes->size(); - [lines addObject: [PBGitGraphLine upperLineFrom: i to: newPos color: (*it)->index()]]; + add_line(lines, ¤tLine, 1, i, newPos,(*it)->index()); } else { - [lines addObject: [PBGitGraphLine upperLineFrom: i to: newPos color: (*it)->index()]]; + add_line(lines, ¤tLine, 1, i, newPos,(*it)->index()); delete *it; } } else { // We are not this commit. currentLanes->push_back(*it); - [lines addObject: [PBGitGraphLine upperLineFrom: i to: currentLanes->size() color: (*it)->index()]]; - [lines addObject: [PBGitGraphLine lowerLineFrom: currentLanes->size() to: currentLanes->size() color: (*it)->index()]]; + add_line(lines, ¤tLine, 1, i, currentLanes->size(),(*it)->index()); + add_line(lines, ¤tLine, 0, currentLanes->size(), currentLanes->size(), (*it)->index()); } // For existing columns, we always just continue straight down // ^^ I don't know what that means anymore :( if (currentLane) - [lines addObject:[PBGitGraphLine lowerLineFrom:newPos to:newPos color: currentLane->index()]]; + add_line(lines, ¤tLine, 0, newPos, newPos,(*it)->index()); else - [lines addObject:[PBGitGraphLine lowerLineFrom:newPos to:newPos color: 0]]; + add_line(lines, ¤tLine, 0, newPos, newPos, 0); } } //Add your own parents @@ -86,7 +97,7 @@ - (void) decorateCommit: (PBGitCommit *) commit PBGitLane *newLane = new PBGitLane([commit.parents objectAtIndex:0]); currentLanes->push_back(newLane); newPos = currentLanes->size(); - [lines addObject:[PBGitGraphLine lowerLineFrom: newPos to: newPos color: newLane->index()]]; + add_line(lines, ¤tLine, 0, newPos, newPos, newLane->index()); } // Add all other parents @@ -102,7 +113,7 @@ - (void) decorateCommit: (PBGitCommit *) commit for (; it < currentLanes->end(); ++it) { i++; if ((*it)->isCommit(parent)) { - [lines addObject:[PBGitGraphLine lowerLineFrom: i to: newPos color: (*it)->index()]]; + add_line(lines, ¤tLine, 0, i, newPos,(*it)->index()); was_displayed = YES; break; } @@ -117,10 +128,14 @@ - (void) decorateCommit: (PBGitCommit *) commit addedParent = YES; PBGitLane *newLane = new PBGitLane(parent); currentLanes->push_back(newLane); - [lines addObject:[PBGitGraphLine lowerLineFrom: currentLanes->size() to: newPos color: newLane->index()]]; + add_line(lines, ¤tLine, 0, currentLanes->size(), newPos, newLane->index()); } previous = [[PBGraphCellInfo alloc] initWithPosition:newPos andLines:lines]; + if (currentLine > maxLines) + NSLog(@"Number of lines: %i vs allocated: %i", currentLine, maxLines); + + previous.nLines = currentLine; previous.sign = commit.sign; // If a parent was added, we have room to not indent. diff --git a/PBGitRevisionCell.m b/PBGitRevisionCell.m index ac28c9e8f..0d3ce9cd8 100644 --- a/PBGitRevisionCell.m +++ b/PBGitRevisionCell.m @@ -214,11 +214,13 @@ - (void) drawWithFrame: (NSRect) rect inView:(NSView *)view NSRect ownRect; NSDivideRect(rect, &ownRect, &rect, pathWidth, NSMinXEdge); - for (PBGitGraphLine* line in cellInfo.lines) { - if (line.upper == 0) - [self drawLineFromColumn: line.from toColumn: line.to inRect:ownRect offset: ownRect.size.height color: line.colorIndex]; + int i; + struct PBGitGraphLine *lines = cellInfo.lines; + for (i = 0; i < cellInfo.nLines; i++) { + if (lines[i].upper == 0) + [self drawLineFromColumn: lines[i].from toColumn: lines[i].to inRect:ownRect offset: ownRect.size.height color: lines[i].colorIndex]; else - [self drawLineFromColumn: line.from toColumn: line.to inRect:ownRect offset: 0 color:line.colorIndex]; + [self drawLineFromColumn: lines[i].from toColumn: lines[i].to inRect:ownRect offset: 0 color:lines[i].colorIndex]; } if (cellInfo.sign == '<' || cellInfo.sign == '>') diff --git a/PBGraphCellInfo.h b/PBGraphCellInfo.h index 136879b77..3943365f3 100644 --- a/PBGraphCellInfo.h +++ b/PBGraphCellInfo.h @@ -7,20 +7,24 @@ // #import - +#import "PBGitGraphLine.h" @interface PBGraphCellInfo : NSObject { int position; - NSArray* lines; + struct PBGitGraphLine *lines; + int nLines; int numColumns; char sign; NSArray* refs; } -@property(readonly) NSArray* lines; +@property(readonly) struct PBGitGraphLine *lines; +@property(assign) int nLines; + @property(assign) int position, numColumns; @property(assign) char sign; -- (id)initWithPosition: (int) p andLines: (NSArray*) l; + +- (id)initWithPosition: (int) p andLines: (struct PBGitGraphLine *) l; @end \ No newline at end of file diff --git a/PBGraphCellInfo.m b/PBGraphCellInfo.m index f0bd78b3d..e5002cfa0 100644 --- a/PBGraphCellInfo.m +++ b/PBGraphCellInfo.m @@ -10,12 +10,19 @@ @implementation PBGraphCellInfo -@synthesize lines, position, numColumns, sign; -- (id)initWithPosition: (int) p andLines: (NSArray*) l +@synthesize lines, position, numColumns, sign, nLines; +- (id)initWithPosition:(int)p andLines:(struct PBGitGraphLine *)l { position = p; lines = l; return self; } + +-(void) finalize +{ + free(lines); + [super finalize]; +} + @end \ No newline at end of file