Author Topic: Code too slow  (Read 6051 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 :-(

ymg

  • Guest
Re: Code too slow
« Reply #15 on: May 01, 2015, 06:09:43 AM »
Lupo,

Maybe it could be faster if instead of creating Selection Set,
you creates List of "Entity Names".

ymg

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Code too slow
« Reply #16 on: May 01, 2015, 06:46:14 AM »
@ Lupo76:
Maybe using (vla-getxrecorddata) is faster than using (entget)?
But to get an 'instantaneous' selection set you should try ronjonp's advice in post #5: Create additional registered apps.

Note:
In BricsCAD you will not have this issue because you can create an ssget filter using values inside Xdata.
This works in BicsCAD:
Code: [Select]
(ssget "_X" '((-3 ("NOMEMYAPP" (1000 . "TIPOOGG=MARCATURA")))))
(ssget "_X" '((-3 ("NOMEMYAPP" (1000 . "IDFERRO=DEFAULT_*")))))

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Code too slow
« Reply #17 on: May 01, 2015, 09:05:35 AM »
...
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.
...
http://www.theswamp.org/index.php?action=post;quote=544774;topic=49383.0;last_msg=544845

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1454
  • Marco
Re: Code too slow
« Reply #18 on: May 01, 2015, 10:27:23 AM »
Lupo,

Maybe it could be faster if instead of creating Selection Set,
you creates List of "Entity Names".

ymg
CAB code do that:
 >>> (setq result (cons ent result))

Lupo76

  • Bull Frog
  • Posts: 343
Re: Code too slow
« Reply #19 on: May 01, 2015, 11:27:08 AM »
I did some more extensive tests.
Unfortunately I discovered that the slowness is not determined only by the group of selection, but also from the code that handles it later.
With your advice I managed to speed up the creation of group selection.
I also tried the way of the List of "Entity Names".

But now I have to check out the rest of the code.
There is a strange thing though ... to test the speed of the code I inserted between rows, some (princ "\nX"), where "X" is a sequential number.
At a certain point in the code I have inserted the following two lines, one after the other
(princ "\n5")
(princ "\n6")

The number 5 appears immediately, while the number 6 has a delay of about 1 ".
This is very strange if I consider that between (princ "\n5") and (princ "\n6"), there is no code!  :-o

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Code too slow
« Reply #20 on: May 01, 2015, 11:32:01 AM »
What CAD program are you using?
Quote
Non Autodesk DWG.  This DWG file was saved by a software application that was not developed or licensed by Autodesk.  Autodesk cannot guarantee the application compatibility or integrity of this file.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Lupo76

  • Bull Frog
  • Posts: 343
Re: Code too slow
« Reply #21 on: May 01, 2015, 11:34:25 AM »
What CAD program are you using?
Quote
Non Autodesk DWG.  This DWG file was saved by a software application that was not developed or licensed by Autodesk.  Autodesk cannot guarantee the application compatibility or integrity of this file.

BricsCAD V15, however, the application must also be compatible with AutoCAD

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1454
  • Marco
Re: Code too slow
« Reply #22 on: May 01, 2015, 01:00:02 PM »
Lupo,
I advise you to review the structure of the xdata, in particular the meaning of a value should not be the contents of a string but the position or sequence of the pair in the structure
 
Code: [Select]
  (-3
      (
         "EMILISPCA"
         (1000 . "TIPOOGG=FERRO")
         (1000 . "IDFERRO=DEFAULT_1")
         (1000 . "TIPOFERRO=ESPLOSO")
         (1011 118.650976974287 -84.5345340970474 0.0)
         (1011 128.650976974287 -84.5345340970474 0.0)
         (1011 118.650976974287 -74.5345340970474 0.0)
         (1040 . 1.0)
      )
   )
Code: [Select]
  (-3
      (
         "EMILISPCA"
         (1000 . "FERRO")
         (1000 . "DEFAULT_1")
         (1000 . "ESPLOSO")
         (1011 118.650976974287 -84.5345340970474 0.0)
         (1011 128.650976974287 -84.5345340970474 0.0)
         (1011 118.650976974287 -74.5345340970474 0.0)
         (1040 . 1.0)
      )
   )
[code]
So:
1° assoc 1000 > TIPOOGG
2° assoc 1000 > IDFERRO
3° assoc 1000 > TIPOFERRO

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Code too slow
« Reply #23 on: May 01, 2015, 02:35:31 PM »
Regarding the formatting of the xdata I would go a bit further than Marc'Antonio's suggestion:
http://www.theswamp.org/index.php?topic=48868.msg540029#msg540029

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1454
  • Marco
Re: Code too slow
« Reply #24 on: May 02, 2015, 04:14:56 AM »
Regarding the formatting of the xdata I would go a bit further than Marc'Antonio's suggestion:
http://www.theswamp.org/index.php?topic=48868.msg540029#msg540029
Many years ago I had a program  (2d reinforced concrete beams, now abandoned) similar to Lupo's, this is an example of storing information with xdata
Code: [Select]

  (-3
      (
         "2DBEAM_PIL"
         (1002 . "{")
         (1002 . "{")
         (1005 . "418")
         (1070 . 3)
         (1040 . 5.0)
         (1011 252.703096126625 194.012274842227 0.0)
         (1040 . 80.0)
         (1040 . 60.0)
         (1040 . 55.0)
         (1000 . "B")
         (1002 . "}")
         (1002 . "{")
         (1040 . 270.0)
         (1040 . 270.0)
         (1040 . 300.0)
         (1002 . "}")
         (1002 . "{")
         (1040 . 40.0)
         (1040 . 25.0)
         (1040 . 25.0)
         (1040 . 25.0)
         (1002 . "}")
         (1002 . "{")
         (1040 . 15.0)
         (1040 . 10.0)
         (1040 . 15.0)
         (1040 . 15.0)
         (1002 . "}")
         (1002 . "}")
      )
   )
)
  (-3
      (
         "2DBEAM_FER"
         (1002 . "{")
         (1005 . "425")
         (1005 . "418")
         (1000 . "LTot")
         (1000 . "P00FerPil")
         (1002 . "}")
      )
   )




Jeff H

  • Needs a day job
  • Posts: 6151
Re: Code too slow
« Reply #25 on: May 02, 2015, 05:27:59 PM »