加速用Pyinstaller创建的.exe文件

15 投票
2 回答
26915 浏览
提问于 2025-05-17 17:02

我把我的程序(用Python 3.6.1写的,之前用Python 3.5.3转换过)从.py文件转换成了.exe文件,使用的是Pyinstaller。不过,它的加载速度慢得惊人(大约需要16秒,而在IDLE中运行时只需不到1秒),即使我已经优化了我认为的问题(导入了很多模块,所以我把代码改成只导入必要的模块部分)。这样在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()

相关问题:

  • 暂无相关问题
暂无标签

2 个回答

2

试着创建一个虚拟环境,然后在里面运行你的项目。接着在这个虚拟环境中运行pyinstaller,这样你只打包需要的东西。这会帮你省去很多麻烦。

其次,使用onedir选项比使用onefile更快,因为它不需要把所有文件从你的exe解压到临时文件夹。Pyinstaller让你很方便地使用其他安装程序把它移动到程序文件夹,并在开始菜单里创建一个快捷方式。

15

看看这个文档,我想里面解释了为什么它运行得慢: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

撰写回答