web-dev-qa-db-fra.com

L'application créée avec PyInstaller a un démarrage lent

J'ai une application écrite en Python et 'compilée' avec PyInstaller. Elle utilise également PyQt pour le framework GUI.

L'exécution de cette application a un délai d'environ 10 secondes avant le chargement de la fenêtre principale et s'affiche. Pour autant que je sache, ce n'est pas dû à la lenteur de mon code. Au lieu de cela, je pense que cela est dû à l'initialisation du runtime Python.

Le problème est que cette application est démarrée avec une application de lancement/barre des tâches personnalisée. L'utilisateur cliquera sur le bouton pour lancer l'application, ne verra rien se produire et cliquera ailleurs sur une autre application. Lorsque mon application affiche sa fenêtre, elle ne peut pas apparaître au premier plan en raison des règles de SetForegroundWindow.

J'ai accès à la source du chargeur PyInstaller win32, du code Python, et même du code du lanceur.

Mes questions sont:

  • Comment accélérer le démarrage de cette application?

  • Comment puis-je mesurer le temps passé pendant les premières secondes de la durée de vie du processus?

  • Quelle est la technique généralement acceptée pour réduire le temps jusqu'à l'affichage de la première fenêtre?

Je voudrais éviter d'ajouter un écran de démarrage pour deux raisons - premièrement, je pense que cela n'aidera pas (la surcharge est avant Python s'exécute) et deux, je n'aime tout simplement pas écrans de démarrage :)

Si je le dois, je pourrais probablement modifier le talon du chargeur PyInstaller pour créer une fenêtre, mais c'est une autre voie que je préfère ne pas prendre.

36
EB.

J'ai "compilé" quelques applications wxPython en utilisant py2exe et cx_Freeze, aucune d'entre elles ne prend plus de 4 secondes pour démarrer.

  • Êtes-vous sûr que ce n'est pas votre code? peut-être un réseau ou un appel de ressources d'E/S contenant votre application?
  • Avez-vous essayé une autre machine que la vôtre? Même le matériel le plus rapide peut être lent parfois avec une mauvaise configuration logicielle, des applications ou un système d'exploitation, essayez-le.
  • Essayez de le chronométrer avec le module timeit.

Je n'ai jamais utilisé pyQT, mais avec wxPython la vitesse de démarrage est OK, et après la première initialisation si je ferme et rouvre, c'est plus rapide que la première fois.

2
Not a privileged user

Dites à PyInstaller de créer un exécutable en mode console. Cela vous donne une console de travail que vous pouvez utiliser pour le débogage.

En haut de votre script principal, avant même que la première importation ne soit exécutée, ajoutez une impression "Code Python commençant". Exécutez ensuite votre exécutable compressé à partir de la ligne de commande. De cette façon, vous pouvez obtenir une image claire, que le temps soit passé dans le chargeur de démarrage de PyInstaller ou dans votre application.

Le chargeur de démarrage de PyInstaller est généralement assez rapide en mode un répertoire, mais il peut être beaucoup plus lent en mode un fichier, car il dépose tout dans un répertoire temporaire. Sous Windows, les E/S sont très lentes, puis vous avez des antivirus qui voudront vérifier tous ces fichiers DLL.

PyQt lui-même n'est pas un problème. PyQt est généré par SIP qui génère des liaisons paresseuses très rapides; l'importation de la totalité de PyQt est plus rapide que toute autre bibliothèque GUI car elle ne fait essentiellement rien: toutes les liaisons aux classes/fonctions sont créées dynamiquement lorsque (et si!) vous y accédez, économisant également beaucoup de mémoire.

Si votre application tarde à venir, ce sera également le cas sans PyInstaller. Dans ce cas, votre seule solution est soit un écran de démarrage (importez uniquement PyQt, créez QApplication, créez un affichage de l'écran de démarrage, puis importez le reste de votre programme et exécutez-le), ou retravaillez votre code. Je ne peux pas vous aider beaucoup sans détails.

28
Giovanni Bajo

Je soupçonne que vous utilisez le mode "un fichier" de pyinstaller - ce mode signifie qu'il doit décompresser toutes les bibliothèques dans un répertoire temporaire avant que l'application puisse démarrer. Dans le cas de Qt, ces bibliothèques sont assez volumineuses et mettent quelques secondes à se décompresser. Essayez d'utiliser le mode "un répertoire" et voyez si cela aide?

23
Shish

Je suis d'accord avec les réponses ci-dessus. Mon programme Qt python avait besoin d'environ 5 secondes pour démarrer sur un PC décent lors de l'utilisation du mode onefile. Après avoir changé en --onedir, il n'a fallu qu'une seconde pour démarrer; presque immédiatement après l'utilisateur double-clique sur le fichier exe. Mais l'inconvénient est qu'il y a beaucoup de fichiers dans ce répertoire qui n'est pas si soigné.

5
Russj

Pour mon application, le long temps de démarrage a été presque entièrement causé par le système antivirus. Le désactiver a réduit le démarrage dans mon cas de 3 minutes à moins de 10 secondes!

Pour mettre ces mesures en perspective: mon application était fournie avec des fichiers de données supplémentaires (environ 150 fichiers avec une charge utile de 250 Mo), en plus de transporter Qt et numpy (cela peut dépendre d'Intel MKL, qui ajoute à lui seul 200 Mo supplémentaires au bundle!) dépendances. Le fait que le système testé fonctionne avec un disque SSD n'a même pas beaucoup aidé.

En conclusion: si vous avez une grande application avec beaucoup de dépendances, le temps de démarrage peut être fortement affecté par le système antivirus!

1
normanius

Au cas où quelqu'un aurait toujours ce problème, j'ai résolu le mien en exécutant l'exe localement et non sur des disques partagés. Cela a pris le temps de démarrage de plus d'une minute à moins de 10 secondes.

0
user11886589