使用PyInstaller创建的应用程序启动缓慢

时间:2012-02-27 18:08:45

标签: python windows performance pyinstaller

我有一个用Python编写的应用程序,并用PyInstaller'编译'。它还使用PyQt作为GUI框架。

在主窗口加载并显示之前,运行此应用程序会有大约10秒的延迟。据我所知,这不是因为我的代码缓慢。相反,我怀疑这是由于Python运行时初始化。

问题是此应用程序是使用自定义laucncher /任务栏应用程序启动的。用户将单击按钮以启动应用程序,看不到任何内容,并单击其他应用程序上的其他位置。当我的应用程序显示它的窗口时,由于SetForegroundWindow的规则,它无法到达前台。

我可以访问PyInstaller win32加载程序,Python代码甚至启动程序代码的源代码。

我的问题是:

  • 如何让这个应用程序更快启动?

  • 如何衡量流程生命周期的前几秒花费的时间?

  • 在第一个窗口显示之前减少时间的普遍接受的技术是什么?

我想避免添加启动画面有两个原因 - 一个,我希望它不会有帮助(开销是在Python代码运行之前)和两个,我只是不喜欢启动画面:)

如果我需要,我可以编辑PyInstaller加载程序存根来创建一个窗口,但这是另一种我不愿意接受的路径。

6 个答案:

答案 0 :(得分:20)

告诉PyInstaller创建一个控制台模式的可执行文件。这为您提供了一个可用于调试的工作控制台。

在主脚本的顶部,即使在第一次导入运行之前,添加一个打印“Python Code starting”。然后从命令行运行打包的可执行文件。通过这种方式,您可以清楚地了解PyInstaller的引导加载程序或应用程序中的时间。

PyInstaller的引导加载程序通常在单向模式下非常快,但在单文件模式下它可能会慢得多,因为它将所有内容都解压缩到一个临时目录中。在Windows上,I / O非常慢,然后你有防病毒软件需要仔细检查所有这些DLL文件。

PyQt本身不是问题。 PyQt由SIP生成,它生成非常快速的延迟绑定;导入整个PyQt比任何其他GUI库都要快,因为它基本上什么都不做:所有对类/函数的绑定都是在你访问它们时(以及如果!)动态创建的,从而节省了大量内存。

如果您的应用程序出现缓慢,那么没有PyInstaller也是如此。在这种情况下,您唯一的解决方案是启动屏幕(仅导入PyQt,创建QApplication,创建显示启动画面,然后导入程序的其余部分并运行它),或者重新编写代码。没有细节,我帮不了你。

答案 1 :(得分:16)

我怀疑您正在使用pyinstaller的“一个文件”模式 - 这种模式意味着它必须在应用程序启动之前将所有库解压缩到临时目录。在Qt的情况下,这些库非常大并且需要几秒钟来解压缩。尝试使用“一个目录”模式,看看是否有帮助?

答案 2 :(得分:2)

我使用py2exe和cx_Freeze“编译”了一些wxPython应用程序,其中没有一个需要4秒多的时间才能启动。

  • 你确定这不是你的代码吗? 可能是一些网络或一些I / O资源调用持有你的应用程序?
  • 您尝试过其他机器吗?即使最快的硬件有时也会因为错误的软件配置,应用程序或操作系统而变慢,请尝试使用它。
  • 尝试使用timeit模块计时。

我从未使用过pyQT,但是使用wxPython,启动速度没问题,并且在第一次初始化后,如果我再次关闭并打开,它会比第一次更快。

答案 3 :(得分:2)

我同意上述答案。在使用onefile模式时,我的Qt python程序需要大约5秒才能在一台不错的PC上启动。在我改为--onedir之后,开始只需要大约一秒钟;用户双击exe文件后几乎立即。但缺点是该目录中有许多文件不是​​那么整洁。

答案 4 :(得分:0)

对于我的应用程序,漫长的启动时间几乎完全是由防病毒系统引起的。关闭它会使我的情况下的启动从3分钟减少到不到10秒!

要进行这些测量:我的应用程序捆绑了额外的数据文件(大约150个文件,有效负载为250MB),除了携带Qt和numpy(这可能取决于英特尔MKL,仅此一项就增加了200MB捆绑!)依赖。它甚至对测试系统运行固态驱动器没有多大帮助......

总之:如果你有一个包含大量依赖关系的大型应用程序,那么启动时间可能会受到防病毒系统的强烈影响!

答案 5 :(得分:0)

万一仍然有人遇到此问题,我通过在本地而不是任何共享驱动器上运行exe来解决了我的问题。这将启动时间从一分钟以上缩短到了10秒以下。