2017-05-24 1 views
2

J'ai une question assez "générale". Je développe avec Revit API (avec python), et j'observe parfois que la session Revit devient plus lente lors de mes tests et de mes essais (plus Revit reste ouvert, plus ça semble se produire). Cela ne m'amène pas vraiment au problème, mais ça m'a fait penser à tout ça ..Codage avec l'API Revit: conseils pour réduire l'utilisation de la mémoire?

Donc, comme je n'ai pas d'arrière-plan de programmation, je suis presque sûr que mon code est rempli de vraiment 'peu orthodoxe' des choses qui pourraient être bien meilleures.

Y aurait-il des «trucs et astuces» de base que je pourrais suivre (je veux dire, liés à l'API Revit) pour accélérer la vitesse d'exécution du code? Ou peut-être devrais-je dire: pour aider à réduire l'utilisation de la mémoire? Par exemple, j'ai lu la méthode 'Dispose' disponible, notamment lors de l'utilisation de Transactions (par exemple ici: http://thebuildingcoder.typepad.com/blog/2012/09/disposal-of-revit-api-objects.html), mais ce n'est pas très clair pour moi à la fin si c'est vraiment important à faire ou non (et de plus, puisque j'utilise Python, et je ne sais pas où cela me place dans la discussion sur l'utilisation de "using" ou non)?

Est-ce que je devrais juste 'tout éliminer'? En plus de la méthode 'Dispose', y a-t-il autre chose? Merci beaucoup, Arnaud.

+0

Question : Utilisez-vous pyRevit pour exécuter les scripts python sous Revit? et si oui, quelle version? –

+0

@EhsanIrannejad Oui. J'utilise la version 4.7. – Arnaud

+0

(Et j'utilise RPS et Revit Lookup tout le temps pour aider au débogage.) – Arnaud

Répondre

6

Principes de base:

Bon, nous allons parler ici de quelques points importants:

  • Vous scripts en cours d'exécution sous IronPython qui est une implémentation de Python en langage C#
  • C# usages langagiers Garbage Collectors pour collecter la mémoire inutilisée. Garbage Collector (GC) est un programme qui est exécuté à intervalles réguliers pour collecter les éléments inutilisés. Il utilise une série de techniques pour regrouper et catégoriser les zones de la mémoire cible pour la collecte ultérieure.
  • Votre programme principal est interrompu par le système d'exploitation pour permettre au GC de collecter de la mémoire. Cela signifie que si le GC a besoin de plus de temps pour faire son travail à chaque intervalle, votre programme deviendra lent et vous aurez du retard.

Problème:

maintenant au cœur de cette question: Python est un langage de programmation orienté objet à cœur et IronPython crée objects (similaires aux éléments de Revit en conception) pour tout, de vos variables aux méthodes d'une classe aux fonctions et tout le reste. Cela signifie que tous ces objets doivent être collectés lorsqu'ils ne sont plus utilisés. Lorsque vous utilisez Python comme langage de script pour un programme, il y a généralement un seul python Engine qui exécute toutes les entrées de l'utilisateur.

Toutefois, Revit n'a pas d'invite de commande ni de moteur python associé. Ainsi, chaque fois que vous exécutez un script dans Revit, un nouveau moteur est créé qui exécute le programme et meurt à la fin.

Cela augmente considérablement la quantité de mémoire inutilisée que le CPG doit collecter.

Solution:

Je suis le créateur et mainteneur de pyRevit et ce problème a été résolu dans pyRevit v4.2

La solution était de mettre LightweightScopes = true lors de la création du moteur IronPython et cela forcera le moteur créer des objets plus petits. Cela a considérablement réduit la mémoire utilisée par IronPython et a augmenté le temps jusqu'à ce que l'utilisateur subisse une dégradation des performances Revit.

+2

bonne prise! J'ai ajouté ceci à ma liste de tâches pour RPS! –

0

Désolé je ne peux pas commenter avec une faible réputation, j'utiliser un autre moyen de réduire la mémoire, il est moins jolie que le tour de LightweightScopes, mais il travaille pour le nettoyage d'un temps après les opérations coûteuses:

import gc 

my_object = some_huge_object 

# [operation] 

del my_object # or my_object = [] does the job for a list or dict 
gc.collect()