TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Mark on October 02, 2003, 10:51:19 AM

Title: Another race!! (How fast can you change an entity/object)
Post by: Mark on October 02, 2003, 10:51:19 AM
According to the Developer Documentation
Quote
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?
Title: Another race!! (How fast can you change an entity/object)
Post by: SMadsen on October 02, 2003, 11:02:52 AM
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.
Title: Another race!! (How fast can you change an entity/object)
Post by: rugaroo on October 02, 2003, 11:14:13 AM
Not to be rude, but doesn't anyone in here actually work???... :D
Title: Another race!! (How fast can you change an entity/object)
Post by: daron on October 02, 2003, 11:22:01 AM
SSSShhh!
Title: Another race!! (How fast can you change an entity/object)
Post by: Mark on October 02, 2003, 11:22:19 AM
Were are working........... :D

Here's what I put together Stig. Using your timer function of course.


Code: [Select]

(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
Title: Another race!! (How fast can you change an entity/object)
Post by: SMadsen on October 02, 2003, 11:28:41 AM
Hmm, that's gonna be a hard one to beat :)  Seriously, it is.
Title: Another race!! (How fast can you change an entity/object)
Post by: daron on October 02, 2003, 11:31:31 AM
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
Code: [Select]
Timed CHGCIR: 3.281012
changed code to set radii to 2.0
Code: [Select]
Timed CHGCIR: 3.359024
from 2.0 back to 0.15
Code: [Select]
Timed CHGCIR: 3.311992

Stig, I'll test your's on the same set w/ the same parameters when you're ready.
Title: Another race!! (How fast can you change an entity/object)
Post by: SMadsen on October 02, 2003, 11:45:37 AM
Allrighty, sorry for the delay .. had to write two methods and pick the fastest.

Code: [Select]
(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))
)
Title: Another race!! (How fast can you change an entity/object)
Post by: daron on October 02, 2003, 11:51:21 AM
Stig, same as above:
changed from 0.8154
to 0.15
Code: [Select]
Timed CHGCIRSM: 5.905983
to 2.0
Code: [Select]
Timed CHGCIRSM: 5.937003
back to 0.15
Code: [Select]
Timed CHGCIRSM: 5.890976
Title: Another race!! (How fast can you change an entity/object)
Post by: daron on October 02, 2003, 11:55:15 AM
Let's think here.
Object collection creation, autolisp wins.
Object property modification, ActiveX wins.
What else can we test?
Title: Another race!! (How fast can you change an entity/object)
Post by: SMadsen on October 02, 2003, 11:55:46 AM
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?
Title: Another race!! (How fast can you change an entity/object)
Post by: Mark on October 02, 2003, 12:00:37 PM
Stig, is repeat generally faster than a foreach or even a mapcar-lambda combo?
Title: Another race!! (How fast can you change an entity/object)
Post by: daron on October 02, 2003, 12:10:39 PM
Sure,

Stig's, as entmod is removed
Code: [Select]
Timed CHGCIRSM: 1.016007
with repeat function removed (all of it)
Code: [Select]
Timed CHGCIRSM: 0.094025

Mark's with vlax-for removed
Code: [Select]
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.
Title: Another race!! (How fast can you change an entity/object)
Post by: SMadsen on October 02, 2003, 12:15:22 PM
Really? I thought it was ENTGET that was sucking on the CPU.
Thanks Daron.
Title: Another race!! (How fast can you change an entity/object)
Post by: SMadsen on October 02, 2003, 12:50:01 PM
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):

Code: [Select]
(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)
Title: Another race!! (How fast can you change an entity/object)
Post by: JohnK on October 02, 2003, 12:51:48 PM
damn this is fun.
Title: Another race!! (How fast can you change an entity/object)
Post by: daron on October 02, 2003, 12:58:31 PM
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.
Title: Another race!! (How fast can you change an entity/object)
Post by: SMadsen on October 02, 2003, 01:01:55 PM
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:

Code: [Select]
(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!
Title: Another race!! (How fast can you change an entity/object)
Post by: SMadsen on October 02, 2003, 01:04:54 PM
Code: [Select]
(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... :)
Title: Another race!! (How fast can you change an entity/object)
Post by: daron on October 02, 2003, 01:08:31 PM
Quote from: SMadsen
Oh well, gotta learn while living... :)


Now ain't that the truth.
Title: Another race!! (How fast can you change an entity/object)
Post by: rugaroo on October 02, 2003, 02:47:38 PM
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