加速用Pyinstaller创建的.exe

时间:2017-05-29 21:05:20

标签: python performance python-3.x exe pyinstaller

我已经使用Pyinstaller将我的程序(用Python 3.6.1编写,使用Python 3.5.3转换)从.py转换为.exe。但是,加载非常慢(大约需要16秒,相比于IDLE运行时的<1秒),即使在我已经优化之后我仍然< strong>问题是(导入大量模块,因此我将代码更改为仅导入必要模块的部分)。在IDLE中运行时加速了很多,但是当我创建了一个.exe时,它完全相同(并且我确实检查过我使用了正确的.py文件)。我似乎Pyinstaller只是将您安装在系统上的所有模块打包到.exe中,而不是只包含实际使用的模块的一小部分(使用--onefile时)。我如何确保Pyinstaller仅安装模块的必要部分或以其他方式加速,同时仍然使用--onefile并将其打包成单个.exe文件?

完整代码:

from os import path, remove
from time import sleep
from sys import exit
from getpass import getuser
from mmap import mmap, ACCESS_READ


my_file = "Text To Speech.mp3"
username = getuser()
no_choices = ["no", "nah", "nay", "course not", "don't", "dont", "not"]
yes_choices = ["yes", "yeah", "course", "ye", "yea", "yh", "do"]


def check_and_remove_file():

    active = mixer.get_init()
    if active != None:
        mixer.music.stop()
        mixer.quit()
        quit()
    if path.isfile(my_file):
        remove(my_file)


def get_pause_duration(audio_length, maximum_duration=15):

    default_pause, correction = divmod(audio_length, 12)
    return min(default_pause + bool(correction), maximum_duration)


def exiting():

    check_and_remove_file()
    print("\nGoodbye!")
    exit()


def input_for_tts(message):

    try:

        tts = gTTS(text = input(message))
        tts.save('Text To Speech.mp3')
        with open(my_file) as f:
            m = mmap(f.fileno(), 0, access=ACCESS_READ)
        audio = MP3(my_file)
        audio_length = audio.info.length
        try:
            mixer.init()
        except error:
            print("\nSorry, no audio device was detected. The code cannot complete.")
            m.close()
            exiting()   
        mixer.music.load(m)
        mixer.music.play()
        sleep(audio_length + get_pause_duration(audio_length))
        m.close()
        check_and_remove_file()

    except KeyboardInterrupt:

        exiting()


from pygame import mixer, quit, error
from gtts import gTTS
from mutagen.mp3 import MP3


check_and_remove_file()


input_for_tts("Hello there " + username + ". This program is\nused to output the user's input as speech.\nPlease input something for the program to say: ")


while True:

    try:

        answer = input("\nDo you want to repeat? ").strip().lower()
        if answer in ["n", no_choices] or any(x in answer for x in no_choices):
            exiting()
        elif answer in ["y", yes_choices] or any(x in answer for x in yes_choices):
            input_for_tts("\nPlease input something for the program to say: ")
        else:
            print("\nSorry, I didn't understand that. Please try again with yes or no.")

    except KeyboardInterrupt:

        exiting()

3 个答案:

答案 0 :(得分:7)

查看文档,我想这可以解释为什么它很慢:https://pyinstaller.readthedocs.io/en/stable/operating-mode.html#how-the-one-file-program-works

简短回答,需要提取完整的程序环境并将其写入临时文件夹。

此外,单文件选项与您的预期形成对比:https://pyinstaller.readthedocs.io/en/stable/operating-mode.html#bundling-to-one-file

答案 1 :(得分:0)

尝试制作一个虚拟环境并从那里运行您的项目。然后从虚拟环境内部运行pyinstaller,以便仅打包所需的内容。这将最适合您

第二,onedir选项比onefile更快,因为它不必将exe中的所有文件解压缩到temp文件夹中。 Pyinstaller使使用qny其他安装程序轻松将其移动到程序文件并在启动或其他操作中创建快捷方式。

答案 2 :(得分:0)

所以我知道这有点旧。

尝试使用 --onedir 标志,而不是 --onefile,因为它会加速 exe。
您可能想使用 --onefile 因为它对用户来说更容易,对吗?

您可以使用 PyInstaller 创建一个目录,然后使用类似 Inno Setup 的东西来创建一个安装程序文件。

这样,您的安装程序将处理文件,您的用户除了运行安装程序外无需执行任何操作。当他们打开你的应用时,它会很快打开。

当我使用 --onefile 模式时,我的应用程序可能需要 3-4 秒到 15 秒以上。当我使用目录和安装程序时,它几乎立即打开。

通过安装程序,用户可以选择他们想要存储您的应用程序的位置以及他们是否想要创建桌面快捷方式。如果您的应用适用于 Windows,操作系统会将其识别为已安装的程序。