加速使用 Pyinstaller 创建的 .exe
Speeding up an .exe created with Pyinstaller
我已经使用 Pyinstaller 将我的程序(用 Python 3.6.1 编写,使用 Python 3.5.3 转换)从 .py 转换为 .exe。然而,它在加载时非常慢(大约需要 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()
看看文档,我想这解释了为什么它很慢: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
尝试创建一个虚拟环境并从那里运行你的项目。然后 运行 pyinstaller 来自虚拟环境,所以你只打包你需要的东西。这将最适合你
其次,onedir 选项比 onefile 更快,因为它不必将 exe 中的所有文件解压缩到临时文件夹中。 Pyinstaller 可以很容易地使用 qny 其他安装程序将其移动到程序文件并在启动或其他内容中创建快捷方式。
我已经使用 Pyinstaller 将我的程序(用 Python 3.6.1 编写,使用 Python 3.5.3 转换)从 .py 转换为 .exe。然而,它在加载时非常慢(大约需要 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()
看看文档,我想这解释了为什么它很慢: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
尝试创建一个虚拟环境并从那里运行你的项目。然后 运行 pyinstaller 来自虚拟环境,所以你只打包你需要的东西。这将最适合你
其次,onedir 选项比 onefile 更快,因为它不必将 exe 中的所有文件解压缩到临时文件夹中。 Pyinstaller 可以很容易地使用 qny 其他安装程序将其移动到程序文件并在启动或其他内容中创建快捷方式。