Author Topic: Code too slow  (Read 6061 times)

0 Members and 1 Guest are viewing this topic.

Lupo76

  • Bull Frog
  • Posts: 343
Code too slow
« on: April 30, 2015, 11:15:07 AM »
Hello everyone,
I need to create a selection set with all the objects that contain a specified xdata.
The context is unfortunately a little complicated.

The objects contain xdata similar to the following:
(-3 ("NOMEMYAPP" (1000 . "TYPEOBJ=ARRAYTO") (1000 . "ID=553") (1000 . "FOOT=20") (1000 . "FOOTUT=20")))

I have hundreds of these objects with these xdata, where only changes ID = XXX.
Unfortunately I can not change the structure of xdata because it would mean rewriting the entire application

I currently use the following function but it is too slow:

Code: [Select]
(defun c:test ()
   (setq objset (SelOggXData "NOMEMYAPP" "TYPEOBJ" "ARRAYTO" nil nil))
)

(defun SelOggXData (nomeapp labeldato valdato tipooggetto layoggetto / seleztmp selez n ent1 leggidato)
   (if (AND (/= tipooggetto nil)(/= layoggetto nil))
       (setq selez (ssget "X" (list (cons 0 tipooggetto)(cons 8 layoggetto)(list -3 (list nomeapp)))))
   )
   (if (AND (/= tipooggetto nil)(= layoggetto nil))
       (setq selez (ssget "X" (list (cons 0 tipooggetto)(list -3 (list nomeapp)))))
   )
   (if (AND (= tipooggetto nil)(/= layoggetto nil))
       (setq selez (ssget "X" (list (cons 8 layoggetto)(list -3 (list nomeapp)))))
   )
   (if (AND (= tipooggetto nil)(= layoggetto nil))
       (setq selez (ssget "X" (list (list -3 (list nomeapp)))))
   )
 
  (setq seleztmp (ssadd))

  (if selez
    (repeat (setq n (sslength selez))
      (setq ent (ssname selez (setq n (1- n))))
      (if
        (member
          (cons 1000 (strcat labeldato "=" valdato))
          (cadr (assoc -3 (entget ent (list nomeapp))))
        )
        (ssadd ent seleztmp)
      )
    )
  )
 
  (if (= (sslength seleztmp) 0)
    nil
    seleztmp
  )

)


Do you have any idea to speed up the creation of these groups of selection?


ronjonp

  • Needs a day job
  • Posts: 7531
Re: Code too slow
« Reply #1 on: April 30, 2015, 11:26:13 AM »
Did not look at your code too close but using member is generally pretty slow. Maybe this will help a bit:

Code - Auto/Visual Lisp: [Select]
  1.       (strcat labeldato "=" valdato)
  2.       (vl-princ-to-string (cdr (assoc -3 (entget ent (list nomeapp)))))
  3.     )
  4.   (ssadd ent seleztmp)
  5. )

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Lupo76

  • Bull Frog
  • Posts: 343
Re: Code too slow
« Reply #2 on: April 30, 2015, 11:35:39 AM »
Did not look at your code too close but using member is generally pretty slow. Maybe this will help a bit:

Code - Auto/Visual Lisp: [Select]
  1.       (strcat labeldato "=" valdato)
  2.       (vl-princ-to-string (cdr (assoc -3 (entget ent (list nomeapp)))))
  3.     )
  4.   (ssadd ent seleztmp)
  5. )


Maybe it's a little faster, but I need to speed much more.   :-(

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Code too slow
« Reply #3 on: April 30, 2015, 11:59:18 AM »
Maybe this will help a bit .. but you're still going to have to iterate the selection set which I believe is your problem.
Code - Auto/Visual Lisp: [Select]
  1. (defun seloggxdata (nomeapp labeldato valdato tipooggetto layoggetto / ent n selez)
  2.   (if (setq selez (ssget "X"
  3.                          (list (cons 0
  4.                                      (if tipooggetto
  5.                                        tipooggetto
  6.                                        "*"
  7.                                      )
  8.                                )
  9.                                (cons 8
  10.                                      (if layoggetto
  11.                                        layoggetto
  12.                                        "*"
  13.                                      )
  14.                                )
  15.                                (list -3 (list nomeapp))
  16.                          )
  17.                   )
  18.       )
  19.     (progn (repeat (setq n (sslength selez))
  20.              (setq ent (ssname selez (setq n (1- n))))
  21.              (if (null (vl-string-search
  22.                          (strcat labeldato "=" valdato)
  23.                          (vl-princ-to-string (cdr (assoc -3 (entget ent (list nomeapp)))))
  24.                        )
  25.                  )
  26.                (ssdel ent selez)
  27.              )
  28.            )
  29.            (if (> (sslength selez) 0)
  30.              selez
  31.            )
  32.     )
  33.   )
  34. )


Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Lupo76

  • Bull Frog
  • Posts: 343
Re: Code too slow
« Reply #4 on: April 30, 2015, 12:04:51 PM »
Maybe this will help a bit .. but you're still going to have to iterate the selection set which I believe is your problem.

Unfortunately, your code does not solve.
I think that to solve the problem need a different approach, but I do not know which  :embarrassed:

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Code too slow
« Reply #5 on: April 30, 2015, 12:31:04 PM »
A work around (for speed) is to read your XDATA 1000 text values (not including the "=") and write each one as a registered app to the object, Then filter for the app directly. You could still maintain your other structure .. not elegant but I don't know any other way to noticeably speed this up.

Quick example:
Code - Auto/Visual Lisp: [Select]
  1. '(-3
  2.   ("FOOTUT_20" (1071 . 0))
  3.   ("FOOT_20" (1071 . 0))
  4.   ("ID_553" (1071 . 0))
  5.   ("TYPEOBJ_FOO" (1071 . 0))
  6.   ("NOMEMYAPP" (1000 . "TYPEOBJ=FOO") (1000 . "ID=553") (1000 . "FOOT=20") (1000 . "FOOTUT=20"))
  7.  )
  8. ;; Direct access to selection set
  9. (sssetfirst nil (ssget "X" (list (list -3 (list "TYPEOBJ_FOO")))))
« Last Edit: April 30, 2015, 12:53:45 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: Code too slow
« Reply #6 on: April 30, 2015, 12:47:41 PM »
Removing the strcat from the loop should improve it slightly:

Code - Auto/Visual Lisp: [Select]
  1. (defun seloggxdata ( app lab val typ lay / e i s )
  2.     (setq app (list app)
  3.           val (cons 1000 (strcat lab "=" val))
  4.     )
  5.     (if (setq s
  6.             (ssget "_X"
  7.                 (append
  8.                     (if typ (list (cons 0 typ)))
  9.                     (if lay (list (cons 8 lay)))
  10.                     (list (list -3 app))
  11.                 )
  12.             )
  13.         )
  14.         (repeat (setq i (sslength s))
  15.             (setq e (ssname s (setq i (1- i))))
  16.             (or (vl-position val (cdadr (assoc -3 (entget e app))))
  17.                 (ssdel e s)
  18.             )
  19.         )
  20.     )
  21.     (if (and s (< 0 (sslength s))) s)
  22. )

<< EDIT: replaced member with vl-position >>
« Last Edit: April 30, 2015, 05:28:21 PM by Lee Mac »

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Code too slow
« Reply #7 on: April 30, 2015, 12:49:03 PM »
from Ron's I chose while, and mine returns a LIST not a SS
Code - Auto/Visual Lisp: [Select]
  1. (defun seloggxdata (nomeapp labeldato valdato tipooggetto layoggetto / ent i selez result)
  2.   (if (setq selez (ssget "X"
  3.              (list (cons 0 (if tipooggetto tipooggetto "*"))
  4.                    (cons 8 (if layoggetto layoggetto "*"))
  5.                    (list -3 (list nomeapp))
  6.              )))
  7.     (progn
  8.       (setq i -1)
  9.        (while (setq ent (ssname selez (setq i (1+ i))))
  10.          (if (null (vl-string-search (strcat labeldato "=" valdato)
  11.              (vl-princ-to-string (cdr (assoc -3 (entget ent (list nomeapp)))))))
  12.            (setq result (cons ent result))
  13.          )
  14.     ) ; while
  15.     result
  16.     ) ; progn
  17.   ) ; endif
  18. ) ; defun
« Last Edit: April 30, 2015, 12:52:09 PM by CAB »
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

ymg

  • Guest
Re: Code too slow
« Reply #8 on: April 30, 2015, 02:37:00 PM »
Lee,

If the entity list are long enough (for example polylines)
replacing member by vl-position might be a little improvement.

ymg

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: Code too slow
« Reply #9 on: April 30, 2015, 05:29:18 PM »
If the entity list are long enough (for example polylines)
replacing member by vl-position might be a little improvement.

I was hoping to keep it all Vanilla, but based on the results in your other thread, that looks to be a good call - I have updated the above.

Lupo76

  • Bull Frog
  • Posts: 343
Re: Code too slow
« Reply #10 on: May 01, 2015, 02:50:19 AM »
Thank you all for your help.
There is a slight improvement, but unfortunately I was hoping for something faster.

So at this point I think I have to change the structure of xdata or take another road.  :cry:

Right now I am thinking of the following solution:
1. Rewrite the application to use a new structure of xdata, allowing higher speed when creating selection sets
2. After starting the application, if a user opens a DWG file that contains the old structure of xdata, starts a function that converts it like new.

As I need to save for each object, of different values accompanied by a label, which xdata structure do you recommend for making quick creation of groups of selection, filtering objects by layer, color, object type, one or more label of xdata.

I accept any advice or idea or different approach. 

ymg

  • Guest
Re: Code too slow
« Reply #11 on: May 01, 2015, 03:17:07 AM »
Lupo,

How about posting a typical drawing, so we have an idea
what we are against.

There might be other ways short of changing the whole app.

ymg

Lupo76

  • Bull Frog
  • Posts: 343
Re: Code too slow
« Reply #12 on: May 01, 2015, 03:36:14 AM »
I enclose a simple example of dwg

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1454
  • Marco
Re: Code too slow
« Reply #13 on: May 01, 2015, 04:27:51 AM »
Not tested, try to cycle <selez> with vlax-for:

(vlax-for ObjFor (setq SSlObj (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object))))
  ...
)

---

>>> (cons 1000 (strcat labeldato "=" valdato))

Just do it one time as Lee sample:
>>> val (cons 1000 (strcat lab "=" val))


Lupo76

  • Bull Frog
  • Posts: 343
Re: Code too slow
« Reply #14 on: May 01, 2015, 05:43:19 AM »
Not tested, try to cycle <selez> with vlax-for:

(vlax-for ObjFor (setq SSlObj (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object))))
  ...
)

---

>>> (cons 1000 (strcat labeldato "=" valdato))

Just do it one time as Lee sample:
>>> val (cons 1000 (strcat lab "=" val))

Ciao Marc'Antonio,
Thank you for your reply.
Your code I loved it.
However it did not solve my problem.
Currently after all optimizations, the function takes about 3" processing.
I would be almost instantaneous :-(