Aller au contenu

Messages recommandés

Posté(e)

Bonjour à tous.

 

Jusqu'à présent, j'avais une routine en LiSP qui fonctionnait très bien. Elle plaçait quelques données dans différents attributs des blocs.

 

Cette macro ne m'a jamais posé problème, car je traitais que quelques blocs, mais là, j'ai 8500 blocs à traiter, et le code se met soudain à ralentir.

 

Il traitait plus de cent blocs/seconde, mais arrivé à environ 4000 blocs, il se met sérieusement à ralentir et à 5000 bloc, il n'en traite plus que un par seconde...

 

Arrivé à 5200, c'est 1 toutes les deux secondes... Et c'est de pire en pire...

 

Si quelqu'un a une idée, une astuce voir un conseil, je suis preneur...

 

Voici la boucle qui ralenti...:

  (princ "\nRemplissage des données géographiques des blocs.")
 (if (setq ss (ssget "_X" '((0 . "INSERT"))))
   (progn
     (setq i 0)
     (while (setq ent (ssname ss i))
       (setq i (1+ i))
       (if (= (cdr (assoc 0 elst)) "INSERT")
         (progn
           (setq elst  (entget ent)
                 dxf10 (assoc 10 elst)
                 att   (entget (entnext ent))
                 Coord (cdr (assoc 10 elst))
                 NomBlk (cdr (assoc 2 elst))
           ) ;_ Fin de setq
           (princ "\nTraitement : ")
           (princ i)
           (ade_projsetsrc (ade_projgetwscode))
           (ade_projsetdest "LL-RGF93")
           (setq pntLLRGF93 (ade_projptforward Coord))
           ;;Ecriture des coordonnées dans un fichier CSV
           (write-line (strcat NomBlk "," (rtos (car pntLLRGF93) 2 15) "," (rtos (cadr pntLLRGF93) 2 15))  FileCSV)
           (while (/= (cdr (assoc 0 att)) "SEQEND")
             (cond ((= (cdr (assoc 2 att)) "X")
                    (setq att (subst (cons 1 (rtos (car pntLLRGF93) 2 15)) (assoc 1 att) att))
                    (entmod att)
                   ) ;_ Fin de cond
                   ((= (cdr (assoc 2 att)) "Y")
                    (setq att (subst (cons 1 (rtos (cadr pntLLRGF93) 2 15)) (assoc 1 att) att))
                    (entmod att)
                   )
                   ((= (cdr (assoc 2 att)) "Z-TN")
                    (setq att (subst (cons 1 (rtos (caddr Coord) 2 3)) (assoc 1 att) att))
                    (entmod att)
                   )
                   ((= (cdr (assoc 2 att)) "NOMENTRGEO")
                    (setq att (subst (cons 1 "CERENE") (assoc 1 att) att))
                    (entmod att)
                   )
                   ((= (cdr (assoc 2 att)) "DATERELEVE")
                    (setq Now (menucmd "M=$(edtime,$(getvar,date),DD/MO/YYYY)"))
                    (setq att (subst (cons 1 Now) (assoc 1 att) att))
                    (entmod att)
                   )
                   ((= (cdr (assoc 2 att)) "NOMPRESTACERTIGEO")
                    (setq att (subst (cons 1 NomOp) (assoc 1 att) att))
                    (entmod att)
                   )
                   ((= (cdr (assoc 2 att)) "MARQUEAPP")
                    (setq att (subst (cons 1 NomMateriel) (assoc 1 att) att))
                    (entmod att)
                   )
                   ((= (cdr (assoc 2 att)) "NUMSERIEAPP")
                    (setq att (subst (cons 1 NumMateriel) (assoc 1 att) att))
                    (entmod att)
                   )
                   ((= (cdr (assoc 2 att)) "NUMSERIE")
                    (setq att (subst (cons 1 NumMateriel) (assoc 1 att) att))
                    (entmod att)
                   )
                   ((= (cdr (assoc 2 att)) "INCERTXY")
                    (setq att (subst (cons 1 "5cm") (assoc 1 att) att))
                    (entmod att)
                   )
                   ((= (cdr (assoc 2 att)) "INCERTZ")
                    (setq att (subst (cons 1 "5cm") (assoc 1 att) att))
                    (entmod att)
                   )
             ) ;_ Fin de cond
             (setq att (entget (entnext (cdr (assoc -1 att)))))
           ) ;_ Fin de while
         ) ;_ Fin de progn
       ) ;_ Fin de if
     ) ;_ Fin de while
   ) ;_ Fin de progn
 ) ;_ Fin de if

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

Salut,

 

Tu dois pouvoir supprimer certaines chose inutiles comme le test :

(if (= (cdr (assoc 0 elst)) "INSERT")

vu que tu utilises un filtre de sélection (par ailleurs, la variable elst n'est pas renseignée à ce stade...).

 

La variable dxf10 semble inutile.

 

Tu peux aussi créer une variable (setq tag (cdr (assoc 2 att))) avant le (cond ...) pour éviter d'évaluer (cdr (assoc 2 att)) à chaque fois.

 

Mais je ne suis pas certain que tout ça te fasse gagner énormément.

 

Par ailleurs, je ne sais pas ce que font les fonctions LISP spécifque MAP (ade_*) et donc si elles sont "couteuses".

 

Un autre truc à essayer, serait de stocker les données de chaque bloc dans une liste pendant la boucle (une chaîne de caractères par ligne) et d'écrire le fichier CSV à partir de cette liste dans une autre boucle (foreach).

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Salut

 

Peut-être en utilisant le vlisp

Essaye ceci (non testé)

  (princ "\nRemplissage des données géographiques des blocs.")
 (setq doc (vla-get-activedocument (vlax-get-acad-object)))
 (and (ssget "_X" '((0 . "INSERT"))))
   (progn
     (vlax-for ent (setq sel (vla-get-activeselectionset doc))
(ade_projsetsrc (ade_projgetwscode))
(ade_projsetdest "LL-RGF93")
(setq pntLLRGF93 (ade_projptforward Coord))
;;Ecriture des coordonnées dans un fichier CSV
(write-line (strcat (vla-get-name ent) "," (rtos (car pntLLRGF93) 2 15) "," (rtos (cadr pntLLRGF93) 2 15))  FileCSV)
(foreach att (vlax-invoke ent 'getattributes)
  (cond
    ((= (vla-get-tagstring att) "X")
      (vla-put-textstring att (rtos (car pntLLRGF93) 2 15))
    ) ;_ Fin de cond
    ((= (vla-get-tagstring att) "Y")
      (vla-put-textstring att (rtos (cadr pntLLRGF93) 2 15))
    )
    ((= (vla-get-tagstring att) "Z-TN")
      (vla-put-textstring att (rtos (caddr Coord) 2 3))
    )
    ((= (vla-get-tagstring att) "NOMENTRGEO")
      (vla-put-textstring att "CERENE")
    )
    ((= (vla-get-tagstring att) "DATERELEVE")
      (vla-put-textstring att (menucmd "M=$(edtime,$(getvar,date),DD/MO/YYYY)"))
    )
    ((= (vla-get-tagstring att) "NOMPRESTACERTIGEO")
      (vla-put-textstring att NomOp)
    )
    ((= (vla-get-tagstring att) "MARQUEAPP")
      (vla-put-textstring att NomMateriel)
    )
    ((= (vla-get-tagstring att) "NUMSERIEAPP")
      (vla-put-textstring att NumMateriel)
    )
    ((= (vla-get-tagstring att) "NUMSERIE")
      (vla-put-textstring att NumMateriel)
    )
    ((= (vla-get-tagstring att) "INCERTXY")
      (vla-put-textstring att "5cm")
    )
    ((= (vla-get-tagstring att) "INCERTZ")
      (vla-put-textstring att "5cm")
    )
  )
)
     )
     (vla-delete sel)
   )
 )

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Posté(e)

Bonjour à vous, et merci messieurs pour votre aide...

 

En fait, dans ma routine, j'insérais les 8500 blocs, puis attribuais les 11 valeurs aux 8500 blocs et ensuite, écrivais les coordonnées des blocs dans un fichier .csv. Trois boucles...

 

Mais grace à la réponse de (gile) sur un autre post, je fais tout en une seule fois, et ça ne prend que quelques minutes... EN une boucle...

 

Encore merci à vous deux qui, tel des Zorro du LiSP, venez à notre secours... ;)

 

Denis...

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

Puisqu'on parle d'optimisation, j'ai fait quelques tests avec benchmark dans le sens de ce que propose Patrick_35. Et j'étais curieux de voir ce que donnait la "nouvelle" fonction setpropertyvalue.

 

J'ai donc écrit 3 fonctions qui établissent la valeur d'un attribut avec entmod (foo), vla-put-Textstring (bar) et setpropertyvalue (baz) :

 

(defun foo (ent tag val / elst)
 (while (and
          (setq ent (entnext ent))
          (= (cdr (assoc 0 (setq elst (entget ent)))) "ATTRIB")
        )
   (if (= (cdr (assoc 2 elst)) tag)
     (entmod (subst (cons 1 val) (assoc 1 elst) elst))
   )
 )
)

(defun bar (blk tag val / atts)
 (foreach att (vlax-invoke blk 'GetAttributes)
   (if (= (vla-get-TagString att) tag)
     (vla-put-TextString att val)
   )
 )
)

(defun baz (blk tag val)
 (vl-catch-all-apply 'setpropertyvalue (list blk tag val))
)

 

Sur un bloc avec 2 attributs, on note que si l'utilisation de Visual LISP est un peu plus rapide que entmod, c'est setpropertyvalue qui semble la plus rapide.

_$ (benchmark '((foo blk "ATT1" "FOO") (bar vl_blk "ATT1" "BAR") (baz blk "ATT1" "BAZ")))
Benchmarking .................Elapsed milliseconds / relative speed for 16384 iteration(s):

   (BAZ BLK "ATT2" "BAZ")........1404 / 1.46 <fastest>
   (BAR VL_BLK "ATT2" "BAR").....1748 / 1.17
   (FOO BLK "ATT2" "FOO")........2043 / 1 <slowest>

 

Mais avec un bloc ayant 12 attributs (de ATT1 à ATT12), l'écart se creuse :

_$ (benchmark '((foo blk "ATT12" "FOO") (bar vl_blk "ATT12" "BAR") (baz blk "ATT12" "BAZ")))
Benchmarking .................Elapsed milliseconds / relative speed for 16384 iteration(s):

   (BAZ BLK "ATT12" "BAZ")........1389 / 2.73 <fastest>
   (BAR VL_BLK "ATT12" "BAR").....3400 / 1.12
   (FOO BLK "ATT12" "FOO")........3791 / 1 <slowest>

 

J'ai voulu pousser un peu avec une fonction utilisant entmod dans une fonction optimisée. Le fait d'utiliser une boucle (while ...) permet de sortir de la boucle dès que l'attribut a été trouvé.

 

(defun foo2 (blk tag val / ent elst)
 (setq ent (entnext blk))
 (while (and ent
             (= (cdr (assoc 0 (setq elst (entget ent)))) "ATTRIB")
        )
   (if (= (cdr (assoc 2 elst)) tag)
     (progn
       (entmod (subst (cons 1 val) (assoc 1 elst) elst))
       (setq ent nil)
     )
     (setq ent (entnext ent))
   )
 )
)

 

Toujours avec le bloc ayant 12 attributs, mais en ciblant le premier bloc (condition optimale pour foo2).

_$ (benchmark '((foo2 blk "ATT1" "FOO") (bar vl_blk "ATT1" "BAR") (baz blk "ATT1" "BAZ")))
Benchmarking .................Elapsed milliseconds / relative speed for 16384 iteration(s):

   (BAZ BLK "ATT1" "BAZ")........1373 / 2.48 <fastest>
   (FOO2 BLK "ATT1" "FOO").......1419 / 2.4
   (BAR VL_BLK "ATT1" "BAR").....3401 / 1 <slowest>

en ciblant le dernier bloc, la performance est logiquement équivalent à celle de foo qui parcourt tous les attributs.

 

Ceci tendrait donc à montrer que l'utilisation de setpropertyvalue avec un étiquette d'attribut est équivalent à un accès direct, probablement dû l'utilisation dans l'implémentation d'une table de hachage ou d'un dictionnaire.

 

Maintenant, il n'est pas certain que pour établir les valeurs de tous (ou presque) les attributs d'un bloc setpropertyvalue soit plus efficace si la table de hachage doit être recréée à chaque attribut...

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Ceci tendrait donc à montrer que l'utilisation de setpropertyvalue avec un étiquette d'attribut est équivalent à un accès direct, probablement dû l'utilisation dans l'implémentation d'une table de hachage ou d'un dictionnaire.

 

Maintenant, il n'est pas certain que pour établir les valeurs de tous (ou presque) les attributs d'un bloc setpropertyvalue soit plus efficace si la table de hachage doit être recréée à chaque attribut...

Comme quoi, il ne faut pas rester sur ses acquis.

 

Merci (gile)

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité