Olivier Eckmann Posté(e) le 26 juin 2014 Posté(e) le 26 juin 2014 Bonjour, J'ai écrit des fonctions qui permettent de récupérer les propriétés des objets, par ex la couleur, le calque, le type de ligne, puis selon les objets, l'altitude, le point d'insertion, le style de texte, etc...Chaque fonction est écrite sur le même principe:- passage d'un ObjectId en paramètre- vérification que cet ObjectId est valide, non nul et non erased.- démarrage d'une transaction dans un using- ouverture de l'objet en mode Read- lecture de la propriété- la fin du using termine la transaction et fait le ménage...- la fonction renvoie la valeur de la propriété lue.Tout fonctionne parfaitement.Le problème est que je dois contrôler la structure d'un DWG donc pour chaque objet, je dois contrôler 4 à 8 propriétés par rapport à un cahier des charges. Les temps de comparaison est très long (environ 1 minute pour un dessin de 4000 objets).J'ai donc fait un test simple avec 2 approches différentes:- Cas1 : un programme qui utilisent mes fonctions permettant d'extraire à chaque fois une propriété - Cas 2 : un programme qui utilise une seule transaction, ouvre un objet, récupère les propriétés souhaitées, puis passe à l'objet suivant, etc...Dans le 1er cas le programme met 40 secondes pour balayer mon dessin contenant 10000 polylignes alors que dans le 2ème cas il met moins d'une seconde.N'ayant pas envie de dupliquer mon code de lecture des propriétés pour chaque type d'objet, y a-t-il un moyen d'accélérer le traitement avec la bib de fonctions déjà écrite? ou modifier la manière d'accéder à mes objets pour ne pas perdre autant de temps?Merci.Olivier
Maxence DELANNOY Posté(e) le 26 juin 2014 Posté(e) le 26 juin 2014 Il ne faut pas démarrer une transaction dans une fonction. Utilise TransactionManager.GetObject pour obtenir ton objet via la transaction de plus haut niveau (TopTransaction). Tu peux aussi utiliser ObjectId.GetObject mais il parait que c'est un peu plus lent : http://adndevblog.typepad.com/autocad/2012/07/objectidgetobject.html Maxence DELANNOYDéveloppement de compléments aux logiciels Autodesk : AutoCAD, Revit, Inventor, Vault, Navisworks... et autres logiciels de CAOWIIP - http://wiip.fr
Maxence DELANNOY Posté(e) le 26 juin 2014 Posté(e) le 26 juin 2014 Pour les performances, un article intéressant (manque TransactionManager.GetObject malheureusement) : http://spiderinnet1.typepad.com/blog/2012/08/autocad-net-real-performances-of-objectidopengetobject-transaction-and-openclosetransaction.html Maxence DELANNOYDéveloppement de compléments aux logiciels Autodesk : AutoCAD, Revit, Inventor, Vault, Navisworks... et autres logiciels de CAOWIIP - http://wiip.fr
Olivier Eckmann Posté(e) le 26 juin 2014 Auteur Posté(e) le 26 juin 2014 Merci Maxence, mais là je ne comprends pas du tout quand tu dis qu'il ne faut pas démarrer une transaction dans la fonction.Où dois-je démarrer ma transaction? Dans ma commande principale? au chargement (en variable membre) de mon dialogue? Mon dialogue étant non modal, je ne peux pas laisser une transaction ouverte??????. Pour poursuivre mes tests, j'ai modifié ma bib pour passer en paramètre ma transaction ouverte lors du lancement de la fonction d'analyse. Je gagne un facteur 8 (40 s à 5 s), c'est déjà super.A priori j'ai rien compris aux transactions, je vais me pencher sur le problème.Olivier
Maxence DELANNOY Posté(e) le 26 juin 2014 Posté(e) le 26 juin 2014 s pas du tout quand tu dis qu'il ne faut pas démarrer une transaction dans la fonction.Où dois-je démarrer ma transaction? Dans ma commande principale? au chargement (en variable membre) de mon dialogue? Mon dialogue étant non modal, je ne peux pas laisser une transaction ouverte??????. Même si ta fenêtre est modeless, tu dois bien lancer ton traitement sous la forme d'une commande non ? Donc tu lances ta transaction dans cette commande. En général, tu ne dois ouvrir qu'une seule transaction, sauf si tu dois annuler certains parties du traitement (comme l'option Annuler dans la commande LIGNE qui permet d'annuler le dernier segment). Maxence DELANNOYDéveloppement de compléments aux logiciels Autodesk : AutoCAD, Revit, Inventor, Vault, Navisworks... et autres logiciels de CAOWIIP - http://wiip.fr
(gile) Posté(e) le 26 juin 2014 Posté(e) le 26 juin 2014 Salut, D'après ce que j'ai pu comprendre en lisant plusieurs sujets sur la question (je n'ai retrouvé que celui-ci, mais je me souviens aussi de messages -toujours pertinents- de Tony Tanzillo), je vais essayer de faire une petite synthèse. Pour ouvrir un objet héritant du type DBObject il existe principalement deux méthodes ayant chacune des "variantes" :- soit le faire dans une tranaction avec une la méthode Transaction.GetObject() (ou ses variantes TransactionManager.GetObject() et ObjectId.GetObject()); - sot utiliser la méthode "obsolète" ObjectId.Open() (ou la méthode OpenCloseTransaction.GetObject() qui n'est qu'un wrapper pour Open/Close). En plus de permettre d'ouvrir des objets, l'utilisation d'une transaction, crée aussi un groupe d'annulation ce qui permet donc d'annuler ultérieurement les modifications (ou créations) d'objets qui ont été faites au sein de cette transaction. Ceci a évidemment un coup en terme de performances par rapport au simple fait d'ouvrir et de refermer un objet.Il est donc évidemment plus efficient d'utiliser une seule transaction pour ouvrir plusieurs objets (comme tu as pu le noter).Utiliser TransactionManager.GetObject() ou ObjectId.GetObject() serait en fait équivalent à appeler TransactionManager.TopTransaction.GetObject(), ce qui peut-être un tout petit plus couteux que d'utiliser directement cette transaction (passée en argument à une méthode appelée, par exemple). S'il n'y a aucune modification faite aux objets ouverts (en lecture, donc), un groupe d'annulation est inutile et il serait alors plus intéressant d'utiliser la méthode ObjectId.Open() comme le montre Fenton Webb dans le lien donné plus haut.Le principal "inconvénient" avec ObjectId.Open() est le message affiché par Visual Studio concernant "l'obsolescence" de la méthode, sinon on peut utiliser une instruction using pour garantir la fermeture de chaque objet ouvert.Le type OpenCloseTransaction est apparu entre 2007 et 2010 pour permettre d'utiliser le processus Open/Close d'une manière similaire à l'utilisation d'une transaction. Attention toutefois, il ne s'agit pas vraiment d'une transaction classique, par exemple, on ne peut pas récupérer, depuis une méthode appelée, une instance de OpenCloseTransaction créée dans une méthode appelante avec TopTransaction. Les tests dans le lien donné par Maxence semblent infirmer quelque peu ce théorique gain de performances avec Open/Close. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Olivier Eckmann Posté(e) le 30 juin 2014 Auteur Posté(e) le 30 juin 2014 Bonjour, Je reviens de différents tests: - au départ création d'une transaction à chaque ouverture => 40s de traitement- Id.getObbject() qui utilise la TopTransaction => 5 s- passage de la transaction en paramètre pour utiliser tr.getObject() => 4 s- Open/Close direct sur l'objet => moins de 1s. Donc en conclusion :- pour mes fonctions de lecture qui ne modifie pas l'objet, je vais utiliser le Open/Close (pas de possibilité de OpenCloseTransaction car non dispo en 2007 et 2008). Tant pis pour les avertissements de fonction obsolète dans VS.- pour les fonctions qui modifie les propriétés, utilisation d'un paramètre optionnel de type Transaction par défaut null. Si la transaction est passée en paramètre alors utilisation directe, sinon tente de récupérer la toptransaction pour l'utiliser, sinon démarre une transaction. Comme ça je ne change rien à mon code général, et je ne modifie que ma bib qui s'adapte à ce que je lui fournis ou à ce qui est dispo. Merci à vous 2 pour toutes les infos. Olivier
Messages recommandés
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 compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant