Benchmarked: [NSBezierPath containsPoint:]
Benchmarked: [NSBezierPath containsPoint:]
- Subject: Benchmarked: [NSBezierPath containsPoint:]
- From: j o a r <email@hidden>
- Date: Mon, 1 Oct 2001 21:08:21 +0200
On Monday, October 1, 2001, at 05:03 , Simon Stapleton wrote:
I just checked the GNUStep implementation, which appears to be sane.
So it might well be possible to rip that bit out of the GNUStep code,
make a category on NSBezierPath and use that instead, which would
save the overhead of setting up autorelease pools.
...provided that you can live with the GPL licence - I'm not sure I want
that right now.
Anyway - it was an interesting suggestion so I did just that, and timed
looping over that method a few thousand times - I'll present my findings
below.
One very important thing to note is that the two methods didn't return
the same results! I haven't checked out what happens, but it seems like
the GnuStep method doesn't work as it should in my code.
Background:
1) My code is not made for benchmarking, so don't look at the absolute
numbers - only relations between the two implementations
2) My path is a simple path; a rectangle with two straight sides and two
curved.
3) I made the test under a couple of different conditions:
* pool / no pool = wether or not I keep an autorelease pool witin the
loop (Needed for Apple's implementation of containsPoint)
* pre-flattened / un-flattened = Do I call "bezierPathByFlatteningPath"
on the path before the loop?
4) All numbers are in seconds
Using Apple's containsPoint
**************************************************************************
****
with pool, un-flattened
33.214929
33.095239
33.204607
with pool, pre-flattened
6.969607
6.985167
6.951232
Using GnuStep's containsPoint
**************************************************************************
****
no pool, un-flattened
1.934392
1.918959
1.915985
no pool, pre-flattened
7.756869
7.739393
7.883504
with pool, un-flattened
2.052428
2.025396
2.070963
with pool, pre-flattened
8.232033
0.819667
8.245957
As you can see, the GnuStep method could be almost four times as
efficient as Apple's - provided that the path has curved segments.
I'm still not completely satisified with how the GnuStep method is
implemented:
<snip>
double k = 0.25;
for(t = k; t <= 1+k; t += k)
{
x = (p.x+t*(-p.x*3+t*(3*p.x-p.x*t)))+
t*(3*pts[0].x+t*(-6*pts[0].x+pts[0].x*3*t))+
t*t*(pts[1].x*3-pts[1].x*3*t)+pts[2].x*t*t*t;
y = (p.y+t*(-p.y*3+t*(3*p.y-p.y*t)))+
t*(3*pts[0].y+t*(-6*pts[0].y+pts[0].y*3*t))+
t*t*(pts[1].y*3-pts[1].y*3*t)+pts[2].y*t*t*t;
draftPolygon[pcount].x = x;
draftPolygon[pcount].y = y;
pcount++;
}
<snip>
As you see, it loops over *a lot* of points in every curved segment,
something that might be good for the general implementation - but is not
efficient enough for my particular project. I hope to create something
that suits my project better and provides greater performance.
Well, well,
j o a r