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

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

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

问题是这个应用程序是从一个自定义的 laucncher/taskbar 应用程序启动的。用户将点击启动应用程序的按钮,看到什么都没有发生,然后点击另一个应用程序的其他地方。当我的应用程序显示它的窗口时,由于 SetForeground 窗口的规则,它不能出现在前台。

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

我的问题是:

  • 我如何才能使这个应用程序启动得更快?

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

  • 什么是普遍接受的技术,以减少时间,直到第一个窗口显示?

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

如果需要的话,我可以编辑 PyInstaller 加载程序存根来创建一个窗口,但是这是我不愿意采用的另一种方法。

68247 次浏览

我已经“编译”了一些 wxPython 应用程序使用 py2exe 和 cx _ 急冻,没有一个需要超过4秒钟才能启动。

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

我从未使用过 pyQT,但是对于 wxPython,启动速度是可以的,在第一次初始化之后,如果再次关闭并打开,它会比第一次更快。

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

告诉 PyInstaller 创建一个控制台模式的可执行文件。

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

PyInstaller 的引导加载程序在单目录模式下通常相当快,但在单文件模式下可能会慢得多,因为它将所有内容封装到一个临时目录中。在 Windows 上,I/O 是非常慢的,然后你有反病毒程序,将要双重检查所有这些 DLL 文件。

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

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

我同意以上答案。当使用单文件模式时,我的 Qt python 程序需要大约5秒钟才能在一台像样的 PC 上启动。在我更改为—— onedir 之后,启动它只需要大约一秒钟; 几乎是在用户双击 exe 文件之后立即启动。但是缺点是那个目录中有很多文件不是那么整洁。

对于我的应用程序,长时间的启动时间几乎完全是由防病毒系统造成的。在我的情况下,关闭它可以将启动时间从3分钟减少到不到10秒!

为了更好地理解这些测量结果: 我的应用程序捆绑了额外的数据文件(大约150个文件,有效负载为250MB) ,除此之外还带有 Qt 和 numpy (这可能取决于 Intel MKL,它单独向捆绑包添加了另外200MB!)依赖关系。即使测试系统运行在固态驱动器下也没有多大帮助。

总之: 如果您有一个具有很多依赖项的大型应用程序,启动时间可能会受到防病毒系统的强烈影响!

如果还有人有这个问题,我通过在本地而不是在任何 Sharedrive 上运行 exe 来解决我的问题。这使得启动时间从一分多钟缩短到不到10秒。

我通过在反病毒监视软件(F-Secure)中添加一个异常来解决这个问题。它消除了运行前几分钟的等待。