【问题标题】:Speeding up an .exe created with Pyinstaller加速使用 Pyinstaller 创建的 .exe
【发布时间】:2017-10-30 05:20:36
【问题描述】:

我已使用 Pyinstaller 将我的程序(用 Python 3.6.1 编写,使用 Python 3.5.3 转换)从 .py 转换为 .exe。但是,它加载速度非常慢(大约需要 16 秒,而在 IDLE 中运行时需要 我优化了我认为 >问题是(导入大量模块,所以我将代码更改为只导入必要的模块部分)。在 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()

【问题讨论】:

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


    【解决方案1】:

    看看文档,我想这可以解释为什么它很慢: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

    【讨论】:

    • 所以没有办法加快速度?分发一个文件比分发整个文件夹要容易得多,特别是对于那些如果看到一个文件夹中的所有 Python 文件可能不明白他们在看什么的人来说。 .exe 文件在文件夹中有点难找。
    【解决方案2】:

    尝试创建一个虚拟环境并从那里运行您的项目。然后从虚拟环境中运行 pyinstaller,这样你就只打包你需要的东西。这对你最有效

    其次,onedir 选项比 onefile 更快,因为它不必将 exe 中的所有文件解压缩到临时文件夹中。 Pyinstaller 可以很容易地使用 qny 其他安装程序将其移动到程序文件并在启动或其他东西中创建快捷方式。

    【讨论】:

    • 我以为 pyinstaller 只打包脚本导入的依赖项,而不是所有已安装的运行时模块。如果不是这样,应该是。
    • 我好久没用了,不过以前没用过,因为模块可以导入其他模块等等。由于 pip 没有像 npm 或 yarn 那样保留引​​用结构,因此这很容易出错,因为您可以有条件导入、不在文件顶部的导入以及 python 中的许多不同的导入函数。因此,除了使用整个环境之外,没有简单的方法。无论如何,对于每个 python 项目来说,拥有一个 venv 都是一个好主意。当然,使用鸭子打字,使用 python 几乎不可能知道所有包
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-03
    • 2016-06-05
    • 1970-01-01
    相关资源
    最近更新 更多