In article , PeterW wrote:
> PMJI, but would it not be more 'efficient' to use WHILE instead of FOREACH?
I assume you mean because you can terminate the while loop as soon as you
find a point on the line? I checked it out some, and the results are
interesting.
I thought that setting PointsList to nil if I found a matching point would
terminate the foreach. It doesn't. Foreach makes its own local variable
stack for its first argument, and apparently it works off a copy of its
second argument in that stack, which you can't get at to set it to nil.
So it would appear that the speed of foreach versus while would depend on the
length of the point list, whether or not there are any points in the list
that are on the line, and the position of the first point in the list that's
on the line. And it does. Using the following for the "while" version:
(defun IsAnyPointOnLine2 (PointsList LineEName FuzzFactor
/ P1 P2 Elist ReturnValue Counter
)
(setq P1 (cdr (assoc 10 (setq Elist (entget LineEName))))
P2 (cdr (assoc 11 EList))
Counter (length PointsList)
)
(while (and (not ReturnValue) (<= 0 (setq Counter (1- Counter))))
(if (equal (distance P1 P2)
(+ (distance (nth Counter PointsList) P2)
(distance (nth Counter PointsList) P1)
))
FuzzFactor
)
(setq ReturnValue T)
)
)
ReturnValue
)
(note that I'm processing the point list backwards in this version, relative
to the first version).
With a list of 100 points, the while version takes almost 100% longer if none
of the points are on the line and just over 90% less time if the first point
tested is in the list. With ten points in the list, while is about 15%
slower if none of the points are on the line and 60% faster if the first
point tested is on the line. With two points in the list, the two versions
are equal whether or not one of the points is on the line. With ten points
in the list and only the fifth point tested on the line, the while version is
about 17% faster.
So the answer to your question is "maybe, depending on the statistics of the
input data". If you usually expect no points to be on the line, foreach is
faster. If you usually expect at least one of the points to be on the line
and the first point that the routine finds on the line is equally likely to
be at any position in the list, while is probably a tad faster. If you
usually expect at least one of the points to be on the line and it is likely
that one of the points in the first half of the list that the routine
processes, while is better.
jrf
Member of the Autodesk Discussion Forum Moderator Program
Please do not email questions unless you wish to hire my services