python – setuptools为所有脚本增加了150ms的启动延迟
我正在开发一个跨平台的
Python项目.它是一个带有shell自动完成功能的命令行工具,所以速度很重要.
setuptools生成控制台脚本的方式是开销至少150ms – 有时更多.这对于我正在编写的工具来说是完全不可接受的,并且鉴于它在基本情况下的作用很小,因此不应该是必要的. 我正在尝试遵循现代Python项目的最佳实践,所以我使用setuptools来构建项目.该软件包支持windows,因此它为入口点生成二进制包装器的能力至关重要. 无论我如何安装软件包,都会发生这种情况 – pip install,pip install -e,pip install –egg,python setup.py install等. 有一个github issue讨论了这个问题,但到目前为止还没有解决方法或解决方案. 在其他地方,我已经看到人们因此而回到了distutils,但这不是我项目的选择. 我能想到的唯一解决方法是以某种方式扩展或自定义setuptools在按项目安装时所执行的操作,以便二进制填充程序不使用pkg_resources. 我还能做些什么呢?这种相当激烈和无意义的措施呢? 我的setup.py是基本的 – 大致如下: import pip.req import setuptools def install_reqs(): reqs = pip.req.parse_requirements('requirements.txt',session=False) reqs = [str(ir.req) for ir in reqs] return reqs setuptools.setup( name='myproj',version='v1.0.0-dev',packages=setuptools.find_packages(exclude=('tests')),install_requires=install_reqs(),include_package_data=True,entry_points={ 'console_scripts': [ 'myproj = myproj.cli.myproj:main',] },) setuptools为入口点生成的垫片如下所示: !$myhome/.venv/myproj/bin/python # EASY-INSTALL-ENTRY-SCRIPT: 'myproj==1.0.0.dev0','console_scripts','myproj' __requires__ = 'myproj==1.0.0.dev0' import sys from pkg_resources import load_entry_point if __name__ == '__main__': sys.exit( load_entry_point('myproj==1.0.0.dev0','myproj')() ) 以下是使用setuptools生成的控制台脚本的一些cProfile统计信息: ncalls tottime percall cumtime percall filename:lineno(function) 121/1 0.015 0.000 0.278 0.278 {built-in method builtins.exec} 1 0.000 0.000 0.278 0.278 myproj:3(<module>) 125/3 0.001 0.000 0.221 0.074 <frozen importlib._bootstrap>:966(_find_and_load) 125/3 0.001 0.000 0.221 0.074 <frozen importlib._bootstrap>:939(_find_and_load_unlocked) 125/5 0.001 0.000 0.219 0.044 <frozen importlib._bootstrap>:659(_load_unlocked) 99/5 0.001 0.000 0.219 0.044 <frozen importlib._bootstrap_external>:656(exec_module) 152/4 0.000 0.000 0.218 0.054 <frozen importlib._bootstrap>:214(_call_with_frames_removed) 2 0.000 0.000 0.204 0.102 __init__.py:15(<module>) 32/15 0.000 0.000 0.135 0.009 {built-in method builtins.__import__} 1 0.000 0.000 0.088 0.088 __init__.py:540(load_entry_point) 1 0.000 0.000 0.085 0.085 __init__.py:2564(load_entry_point) 1 0.000 0.000 0.083 0.083 __init__.py:2216(load) 这里它是一个没有setuptools垫片的自定义脚本: ncalls tottime percall cumtime percall filename:lineno(function) 58/1 0.006 0.000 0.053 0.053 {built-in method builtins.exec} 1 0.000 0.000 0.053 0.053 test.py:1(<module>) 53/3 0.000 0.000 0.052 0.017 <frozen importlib._bootstrap>:966(_find_and_load) 53/3 0.000 0.000 0.052 0.017 <frozen importlib._bootstrap>:939(_find_and_load_unlocked) 53/5 0.000 0.000 0.051 0.010 <frozen importlib._bootstrap>:659(_load_unlocked) 65/4 0.000 0.000 0.051 0.013 <frozen importlib._bootstrap>:214(_call_with_frames_removed) 45/5 0.000 0.000 0.051 0.010 <frozen importlib._bootstrap_external>:656(exec_module) 自定义脚本 – test.py – 非常简单: from myproj.cli.myproj import main main() 解决方法
如果我使用’pip install’从源代码安装项目,我也看到了这个问题.但是,如果我首先构建二进制轮文件然后安装轮,则生成的垫片似乎不使用pkg_resources并且速度更快.我用cookiecutter项目测试了这个:
https://github.com/audreyr/cookiecutter 如果我克隆这个项目,然后使用原始方法’pip install.’进行安装,生成的可执行脚本包含从pkg_resources导入的(并且很慢): #!/usr/local/opt/python3/bin/python3.5 # EASY-INSTALL-ENTRY-SCRIPT: 'cookiecutter==1.5.1','cookiecutter' __requires__ = 'cookiecutter==1.5.1' import re import sys from pkg_resources import load_entry_point if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script.pyw?|.exe)?$','',sys.argv[0]) sys.exit( load_entry_point('cookiecutter==1.5.1','cookiecutter')() ) 但是,如果我执行以下两个命令: python setup.py bdist_wheel pip install dist/cookiecutter-1.5.1-py2.py3-none-any.whl 生成的填充程序不包含pkg_resources(并且更快): #!/usr/local/opt/python3/bin/python3.5 # -*- coding: utf-8 -*- import re import sys from cookiecutter.__main__ import main if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script.pyw?|.exe)?$',sys.argv[0]) sys.exit(main()) 当我在Windows上尝试后一种方法时,它仍然创建了.exe填充程序. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |