TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Mark on October 02, 2003, 10:51:19 AM
-
According to the Developer Documentation
ActiveX Automation is a new way to work programmatically with the contents of an AutoCADŽ drawing. In many instances, ActiveX works faster than traditional AutoLISP functions in manipulating AutoCAD drawing objects.
.
After getting smoked by Stig in the last race I'm in doubt. I say we put them to a test. What about changing the radius on 10,000 circles?
-
You're on! Not sure if ENTMOD can outperform ActiveX but let's try.
Edited: Timer will be started when it's time to modify radius', right? Not when creating the circles.
-
Not to be rude, but doesn't anyone in here actually work???... :D
-
SSSShhh!
-
Were are working........... :D
Here's what I put together Stig. Using your timer function of course.
(defun startTimer () (setq time (getvar "DATE")))
(defun endTimer (func)
(setq time (- (getvar "DATE") time)
seconds (* 86400.0 (- time (fix time)))
)
(gc)
(outPut seconds func)
)
(defun outPut (secs def)
;(princ "\nPurging...")
;(command "PURGE" "Layers" "*" "N")
(gc)
(princ (strcat "\nTimed " def ": " (rtos secs 2 6)))
(princ)
)
(defun chgCir (/ *mspace*)
(startTimer)
(setq *mspace* (vla-get-ModelSpace
(vla-get-ActiveDocument (vlax-get-acad-object))
)
)
(vlax-for x *mspace*
(if (= (vlax-get-property x 'ObjectName) "AcDbCircle")
(vlax-put-property x 'Radius 0.15)
)
(vlax-release-object x); edited here forgot to release the obj's
)
(endTimer (vl-symbol-name 'chgCir))
); defun
edited by MST
-
Hmm, that's gonna be a hard one to beat :) Seriously, it is.
-
Okay Mark, I timed yours on my 2-800MHz PIII, 1GB Ram, ACAD 2002 w/ 10,000 circles w/ original radii of 0.8154. I'm not creating one this time. Here's your test score.
changed to 0.15
Timed CHGCIR: 3.281012
changed code to set radii to 2.0
Timed CHGCIR: 3.359024
from 2.0 back to 0.15
Timed CHGCIR: 3.311992
Stig, I'll test your's on the same set w/ the same parameters when you're ready.
-
Allrighty, sorry for the delay .. had to write two methods and pick the fastest.
(defun chgCirSM (/ sset cnt entl)
(startTimer)
(setq sset (ssget "X" '((0 . "CIRCLE")))
cnt 0
)
(repeat (sslength sset)
(setq entl (entget (ssname sset cnt))
cnt (1+ cnt)
)
(entmod (subst (cons 40 0.15) (assoc 40 entl) entl))
)
(endTimer (vl-symbol-name 'chgCirSM))
)
-
Stig, same as above:
changed from 0.8154
to 0.15
Timed CHGCIRSM: 5.905983
to 2.0
Timed CHGCIRSM: 5.937003
back to 0.15
Timed CHGCIRSM: 5.890976
-
Let's think here.
Object collection creation, autolisp wins.
Object property modification, ActiveX wins.
What else can we test?
-
Shoot! Thanks Daron. Thought it might be slow.
Can you try and comment out the ENTMOD line and see what the time is for ENTGET'ing and setting the counter alone?
-
Stig, is repeat generally faster than a foreach or even a mapcar-lambda combo?
-
Sure,
Stig's, as entmod is removed
Timed CHGCIRSM: 1.016007
with repeat function removed (all of it)
Timed CHGCIRSM: 0.094025
Mark's with vlax-for removed
Timed CHGCIR: 0.000000
which makes sense, since it is only gathering the active modelspace as opposed to the ssget function which has to collect the entire database and weed out everything but circles. If I could figure out what to address the vlax-for with, I'm sure that number might change slightly.
-
Really? I thought it was ENTGET that was sucking on the CPU.
Thanks Daron.
-
REPEAT is a different structure than FOREACH and MAPCAR. I have no idea how REPEAT is implemented but I think it places pointers to 1. a chunk of code and 2. to a control value. However, because WHILE must evaluate the control value for each run and it (in the test below) seems to be as slow/fast as REPEAT, it could indicate that REPEAT also does this. I don't know.
But FOREACH and MAPCAR uses a different technique. It doesn't have a control value but can simply shift pointers through a list and are therefore faster. Or so is my comprehension of it, at least.
We can put it all to test (not saying each of these defun's are optimized, but it's a starting point):
(defun repeat_it (lst / cnt)
(setq cnt 0)
(startTimer)
(repeat (length lst)
(expt (nth cnt lst) 2.0)
(setq cnt (1+ cnt))
)
(endTimer "repeat_it")
)
(defun while_it (lst / cnt item)
(setq cnt 0)
(startTimer)
(while (setq item (nth cnt lst))
(expt item 2.0)
(setq cnt (1+ cnt))
)
(endTimer "while_it")
)
(defun foreach_it (lst)
(startTimer)
(foreach n lst
(expt n 2.0)
)
(endTimer "foreach_it")
)
(defun mapcar_it (lst)
(startTimer)
(mapcar (function (lambda (n) (expt n 2.0))) lst)
(endTimer "mapcar_it")
)
(defun makeBigList (/ cnt lst)
(setq cnt 1)
(repeat 10000
(setq lst (cons cnt lst)
cnt (1+ cnt)
)
)
lst
)
(setq alist (makeBigList) dummy (princ))
(repeat_it alist)
Timed repeat_it: 3.686965
(while_it alist)
Timed while_it: 3.671998
(foreach_it alist)
Timed foreach_it: 0.078012
(mapcar_it alist)
Timed mapcar_it: 0.063005
Notice that MAPCAR is actually faster than FOREACH (it was in each time of a few tests here anyway)
-
damn this is fun.
-
That is fast, Stig. Thank you all for helping me to figure out those foreach and mapcar subs. I've got some old routines that could definately use an overhaul based on these tests.
-
Actually I think it's the chunk of code between each run that counts, not the actually looping. Try doing some list handling to run through the list instead of counting through it:
(defun repeat_it (lst / cnt)
(setq cnt 0)
(startTimer)
(repeat (length lst)
(expt (car lst) 2.0)
(setq lst (cdr lst))
)
(endTimer "repeat_it")
)
(repeat_it alist)
Timed repeat_it: 0.094025
A quite noticable change!
-
(defun while_it (lst)
(startTimer)
(while lst
(expt (car lst) 2.0)
(setq lst (cdr lst))
)
(endTimer "while_it")
)
(while_it alist)
Timed while_it: 0.078012
Oh well, gotta learn while living... :)
-
Oh well, gotta learn while living... :)
Now ain't that the truth.
-
I wish I worked with you guys....I am sitting here regrading a five acre parcel, while you are all racing around trying to see who can do something quicker....all well...At least I know what I am doing rather than sittin here trying to compete...I would have the only prog that takes over 5 minutes. lol