我使用python的setuptools遇到了一个奇怪的150ms启动惩罚,我构建了一个最小的测试用例,问题仍然存在:
我的项目布局是:
- setup.py
- setuptest
- - __init__.py
- - __main__.py
那个设置.py文件包含:
from setuptools import setup
setup(
name = 'setuptest',
version = '0.1',
packages = ['setuptest'],
entry_points = {
'console_scripts' : ['setuptest = setuptest.__main__:main']
} ,
)
\uuuu main\uuuuuuuuy.py文件只包含:
#!/usr/bin/env python2
def main ():
print "hai"
if __name__ == '__main__':
main()
在项目根目录中执行此操作:
—— — time python2 setuptest
hai
real 0m0.021s
user 0m0.017s
sys 0m0.004s
但是,在运行sudo python2 setup.py install
并执行以下操作之后,脚本的总执行时间为21毫秒:
—— — time setuptest
hai
real 0m0.158s
user 0m0.144s
sys 0m0.012s
—— —
给我158ms。这个+150s的启动延迟时间是一致的,在我使用setuptools时会发生,但在我通过包管理器安装的东西或手动安装其他人的项目时不会发生,这让我觉得我显然做了一些非常错误的事情。你知道吗
如果您使用“python”或“python”从源代码安装项目设置.pyinstall'或'pip install'(创建一个.egg文件)生成的可执行脚本使用pkg\u资源,速度很慢。你知道吗
但是,如果先构建二进制wheel文件(.whl),然后安装wheel,则生成的可执行脚本似乎不会从pkg\u资源导入,而且速度更快。以一个任意项目为例,下面是使用两种不同方法安装cookiecutter项目的结果。你知道吗
https://github.com/audreyr/cookiecutter
如果此项目是使用“python”从源代码安装的设置.pyinstall',生成的可执行脚本包含从pkg\u资源导入的内容(速度慢):
但是,如果使用以下两个命令生成并安装了控制盘文件:
可执行脚本不包含来自pkg\u资源的导入(速度更快):
当您使用setuptools安装软件时,它将在
bin
目录中生成可执行脚本,如下所示:因为
load_entry_point()
将通过sys.path
中所有可用的包进行解析,所以安装的位置和包越多,构建列表并查找列表所需的时间就越长。你知道吗有关更多详细信息,我们需要了解setuptools的
load_entry_point()
实现:从^{} :
从'setuptools.py:get_distribution()':
从^{} :
从^{} :
我会把它放在那里,你可以跟踪到它变得昂贵的地方。我猜在^{} 中完成映射的方法(比如^{} 属性)在执行时可能会非常昂贵。你知道吗
好吧,我自己找到了答案,这让我很困惑,但它说明了为什么其他人更快。事实证明,尽管
setuptools
被推荐为更新更好的,但出于某种原因,它也会增加巨大的性能损失,至少在我的系统上distutils
没有。你知道吗所有快速运行的包都使用了
distutils
将示例编辑为:
其中
bin/disttest
是项目根目录中的一个可执行文件,它作为实际程序的一个普通包装器,完全解决了问题。从distutils.core
导入而不是从setuptools
导入似乎是关键。遗憾的是distuitls
没有方便的入口点机制。你知道吗相关问题 更多 >
编程相关推荐