Re: Speed of Quartz (was: optimizing compilers)
Re: Speed of Quartz (was: optimizing compilers)
- Subject: Re: Speed of Quartz (was: optimizing compilers)
- From: "Erik M. Buck" <email@hidden>
- Date: Mon, 4 Feb 2002 13:14:03 -0600
I think we should put some issues with NSBezierPath to rest.
Here are two simple NSView subclasses. Both draw connected line segments
with 500 points using NSBezierPath -moveToPoint: and -lineToPoint:. A
reasonable expectation is that the first implementation is faster than the
second implementation. The first implementation avoids 500 allocations and
lots of attribute setting operations. If fact, the first implementation is
more than ten times SLOWER than the second implementation. NSBezierPath is
seriously broken.
I have a simple ProjectBuilder project and nib to build and demo both
classes side by side. I will send it to anyone that wants it.
/* MYPathView.h */
#import <Cocoa/Cocoa.h>
#define MYNUM_POINTS (500)
@interface MYPathView : NSView
{
NSPoint _myPoints[MYNUM_POINTS];
}
@end
/* MYPathView.m */
#import "MYPathView.h"
@implementation MYPathView
- (BOOL)isOpaque
{
return YES;
}
- (void)drawRect:(NSRect)aRect
{
NSBezierPath *tempPath = [[NSBezierPath alloc] init];
int i;
NSAssert(MYNUM_POINTS >= 2, @"Compiled with MYNUM_POINTS < 2");
// erase background
[[NSColor whiteColor] set];
[NSBezierPath fillRect:[self bounds]];
// initialize points array with random points in bounds
for(i = 0; i < MYNUM_POINTS; i++)
{
_myPoints[i] = NSMakePoint(random() % (int)[self bounds].size.width,
random() % (int)[self bounds].size.height);
}
// define a single bezier path containing all of the points
[tempPath moveToPoint:_myPoints[0]];
for(i = 1; i < MYNUM_POINTS; i++)
{
[tempPath lineToPoint:_myPoints[i]];
}
// set the attributs to use and stroke the path
[[NSColor greenColor] set];
[tempPath setLineWidth:1.0];
[tempPath setLineCapStyle:NSRoundLineCapStyle];
[tempPath setLineJoinStyle:NSRoundLineJoinStyle];
[tempPath setMiterLimit:4.0];
[tempPath stroke];
}
@end
/* MYPathView2.h */
#import <Cocoa/Cocoa.h>
#define MYNUM_POINTS (500)
@interface MYPathView2 : NSView
{
NSPoint _myPoints[MYNUM_POINTS];
}
@end
/* MYPathView2.m */
#import "MYPathView2.h"
@implementation MYPathView2
- (BOOL)isOpaque
{
return YES;
}
- (void)drawRect:(NSRect)aRect
{
NSBezierPath *tempPath;
int i;
NSAssert(MYNUM_POINTS >= 2, @"Compiled with MYNUM_POINTS < 2");
// erase background
[[NSColor whiteColor] set];
[NSBezierPath fillRect:[self bounds]];
// initialize points array with random points in bounds
for(i = 0; i < MYNUM_POINTS; i++)
{
_myPoints[i] = NSMakePoint(random() % (int)[self bounds].size.width,
random() % (int)[self bounds].size.height);
}
// set the color to use for the lines
[[NSColor greenColor] set];
// define a new bezier path for every two points, set attributes, and
stroke
for(i = 1; i < MYNUM_POINTS; i++)
{
tempPath = [[NSBezierPath alloc] init];
[tempPath moveToPoint:_myPoints[i - 1]];
[tempPath lineToPoint:_myPoints[i]];
[tempPath setLineWidth:1.0];
[tempPath setLineCapStyle:NSRoundLineCapStyle];
[tempPath setLineJoinStyle:NSRoundLineJoinStyle];
[tempPath setMiterLimit:4.0];
[tempPath stroke];
[tempPath release];
}
}
@end