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 16:21:31 -0600
>
On Monday, February 4, 2002, at 11:14 AM, Erik M. Buck wrote:
>
>
>
> // 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];
>
> }
>
>
This is just a guess, but I think that what's killing you here
>
is memory allocation. Every time you add a point to the path,
You would think so, but you have not been following the thread. The whole
point is that the example above is 10 times FASTER against all reason.
>
you're potentially causing a realloc(), which means a round-trip
>
to the malloc table (which means a hash insert.) And of course,
>
creating and destroying paths is far more expensive than
>
clearing and reusing a single path.
I though so too, but the opposite is true. Allocating, initializing,
configuring, and stroking a path over and over INSIDE the loop is 10 times
faster than using just on NSBezierPath instance to draw the same lines.
>
>
What happens when you change this to:
>
>
temPath = [[NSBezierPath alloc] init];
>
[tempPath setLineWidth:1.0];
>
[tempPath setLineCapStyle:NSRoundLineCapStyle];
>
[tempPath setLineJoinStyle:NSRoundLineJoinStyle];
>
[tempPath setMiterLimit:4.0];
>
>
for(i = 1; i < MYNUM_POINTS; i++)
>
{
>
[tempPath moveToPoint:_myPoints[i - 1]];
>
[tempPath lineToPoint:_myPoints[i]];
>
[tempPath stroke];
>
[tempPath removeAllPoints];
>
}
It gets ten times faster than adding all of the points to one path. What
you wrote is faster still. the whole point is that the slowness of Quartz
is dwarfing even repeated allocations within the loop. I made the loop as
slow as I could just to show that the problem is in Quartz and NOT in
NSBezierPath. Note from the CGContext functions example in this thread, the
slowness is not due to NSBezierPath. The slowness is in Quartz.
>
>
I'd also be interested in seeing what just calling [NSBezierPath
>
strokeLineFromPoint:toPoint:] gets you.
This is also faster than one big path with lots of points. The whole point
is that Quartz is ridiculously slow stroking a path with lots of points. It
is much slower than stroking many paths with two points each. This is
direct contrast with expectations. This is the opposite of the similar
Display Postscript user paths test.
I suspect that Quartz is performing look-ups for path crossings during
stroke and that the algorithm is O(N*N).
Since neither Postscript nor Adobe PDF renderers use such shitty algorithms,
I think the fault lies with a shitty implementation of Quartz.
>
>
-jcr
>
>
>
"These kids today don't know the simple joy of saving four bytes
>
of page-0 memory on a 6502" - unknown