EB.
EB.

Reputation: 3555

App created with PyInstaller has a slow startup

I have an application written in Python and 'compiled' with PyInstaller. It also uses PyQt for the GUI framework.

Running this application has a delay of about 10 seconds before the main window loads and is shown. As far as I can tell, this is not due to slowness in my code. Instead, I suspect this is due to the Python runtime initializing.

The problem is that this application is started with a custom laucncher / taskbar application. The user will click the button to launch the app, see nothing appear to happen, and click elsewhere on another application. When my application shows it's window, it cannot come to the foreground due to the rules for SetForegroundWindow.

I have access to the source for the PyInstaller win32 loader, the Python code, and even the launcher code.

My questions are:

I'd like to avoid adding a splash screen for two reasons - one, I expect it won't help (the overhead is before Python code runs) and two, I just don't like splash screens :)

If I need to, I could probably edit the PyInstaller loader stub to create a window, but that's another route i'd rather not take.

Upvotes: 106

Views: 101348

Answers (10)

eos1d3
eos1d3

Reputation: 413

No matter what settings are for PyInstaller, the start time is very slow, especially on slow machine. It takes around 20 seconds on my slow machine.

Just do not use PyInstaller. This software is poorly developed. I finally switch to nuitka. It supports tk-inter without any issue. And start time is just 1 to 2 seconds. A example script example here:

python -m nuitka ^
  --onefile ^
  --windows-icon-from-ico="icon.png" ^
  --windows-product-version="1.4.1" ^
  --enable-plugin=tk-inter ^
  --enable-plugin=no-qt ^
  --windows-console-mode=disable ^
  --include-data-file=theme_win.json=theme_win.json ^
  --output-dir="dist" ^
  main.py

Upvotes: 2

momomuchu
momomuchu

Reputation: 11

may be late but a way that works is to add this line in the start and activate the console it hide the console while keeping the start-up speed efficient

    import ctypes
    ctypes.windll.user32.ShowWindow(ctypes.windll.kernel32.GetConsoleWindow(), 0)

Upvotes: 1

Jun
Jun

Reputation: 91

I had the same slow launch issue, and I ended up using the "--onedir" option instead,but creating a shortcut to a folder above the distribution folder created by pyinstaller so I could easily find the executable.

the following is the batch command "build.bat"

--

rem build with pyinstaller

C:\Python310\Scripts\pyinstaller.exe --onedir -w --noconfirm MyProg.py

rem create shortcut

set TARGET='C:\MyProgDir\dist\MyProg.exe'
set SHORTCUT='C:\MyProgDir\MyProg.exe.lnk'
set PWS=powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile
%PWS% -Command "$ws = New-Object -ComObject WScript.Shell; $s = $ws.CreateShortcut(%SHORTCUT%); $S.TargetPath = %TARGET%; $S.Save()"

Upvotes: 2

Termintenator
Termintenator

Reputation: 31

I solved this by adding an exception to the anti-virus monitoring software (F-Secure). It removed the wait of several minutes before running.

Upvotes: 3

user11886589
user11886589

Reputation: 49

In case anyone is still have this issue, I resolved mine by running the exe locally and not on any sharedrives. This took the startup time from over a minute to under 10 seconds.

Upvotes: 4

normanius
normanius

Reputation: 9762

For my application, the long startup time almost entirely was caused by the antivirus system. Switching it off reduced the startup in my case from 3 minutes to less than 10secs!

To bring these measurements into perspective: My application was bundled with extra data files (about 150 files with a payload of 250MB), besides carrying around Qt and numpy (that may depend on Intel MKL, which alone adds another 200MB to the bundle!) dependencies. It even didn't help much that the tested system was running with a solid state drive...

In conclusion: if you have a large application with lots of dependencies, the startup time may be affected strongly by the antivirus system!

Upvotes: 4

Russj
Russj

Reputation: 727

I agree with above answers. My Qt python program needed about 5 seconds to start up on a decent PC when using onefile mode. After I change to --onedir, it only took around one second to start; almost immediately after user double clicks the exe file. But the drawback is that there are many files in that directory which is not so neat.

Upvotes: 17

Giovanni Bajo
Giovanni Bajo

Reputation: 1397

Tell PyInstaller to create a console-mode executable. This gives you a working console you can use for debugging.

At the top of your main script, even before the first import is run, add a print "Python Code starting". Then run your packaged executable from the command line. This way you can get a clear picture whether the time is spent in PyInstaller's bootloader or in your application.

PyInstaller's bootloader is usually quite fast in one-dir mode, but it can be much slower in one-file mode, because it depacks everything into a temporary directory. On Windows, I/O is very slow, and then you have antiviruses that will want to double check all those DLL files.

PyQt itself is a non-issue. PyQt is generated by SIP which generates very fast lazy bindings; importing the whole PyQt is faster than any other GUI library because it basically does nothing: all bindings to classes/functions are dynamically created when (and if!) you access them, saving lots of memory too.

If your application is slow at coming up, that will be true without PyInstaller as well. In that case, your only solution is either a splash screen (import just PyQt, create QApplication, create a display the splashscreen, then import the rest of your program and run it), or rework your code. I can't help you much without details.

Upvotes: 54

Shish
Shish

Reputation: 2980

I suspect that you're using pyinstaller's "one file" mode -- this mode means that it has to unpack all of the libraries to a temporary directory before the app can start. In the case of Qt, these libraries are quite large and take a few seconds to decompress. Try using the "one directory" mode and see if that helps?

Upvotes: 93

Not a privileged user
Not a privileged user

Reputation: 963

I have 'compiled' a few wxPython apps using py2exe and cx_Freeze, None of them take more than 4 seconds to start.

  • Are you sure sure it's not your code ? maybe some network or some I/O resource call holding your app ?
  • Have you tried other machine than yours? Even the fastest hardware can be slow sometimes with the wrong software config, apps or OS, try it.
  • Try timing it with timeit module.

I never used pyQT, but with wxPython the startup speed is OK, and after the first initialize if I close and open again, it's faster than the first time.

Upvotes: 1

Related Questions