一个用于记录导入每个依赖项所需时间的命令行工具。
项目描述
benchmark-imports
一个用于记录Python项目中每个依赖项导入所需时间的命令行工具。当您的代码的导入时间很重要时使用它。
用法
安装
python3 -m pip install benchmark-imports
使用
python3 -m benchmark_imports my_module_name
例如,测量numpy的导入时间
python3 -m pip install numpy
python3 -m benchmark_imports numpy
故障排除
- 为了能够导入您的模块及其所有依赖项,工具必须与测试模块及其所有依赖项在相同的环境中安装。
- 请注意,该工具实际上会导入和执行给定的模块及其所有依赖项。因此,不要在不可信的代码或可能在导入时破坏某些内容的代码上运行它。
- 工具将在结束时报告某些模块在导入时发生的错误列表,但被其他模块抑制。这并不意味着有问题。例如,它可能表明库有一个可选依赖项,它尝试导入但在不可用的情况下忽略它。然而,这意味着在某些环境中模块将被成功导入,因此导入时间可能会有所不同。
提高导入时间
当您确定了慢速模块时,您可以这样做
- 减少耦合。“一点点复制比一点点依赖要好”。例如,如果您只为了使用单个小的函数(如numpy中的numpy.sign)而导入numpy,就自行实现这个函数。
- 使用局部导入。最佳实践是将导入语句放在文件的最顶层。但是,如果这是一个运行速度较慢的模块,并且仅在很少调用的函数中使用,只需将该导入移动到函数体内部即可。这不会使函数变慢很多(当然,除了第一次调用时),因为Python将所有导入缓存到sys.modules。
- 使用延迟导入。这与函数局部导入的想法相似:模块实际上只有在第一次尝试使用时才会导入和执行。这可以通过deferred-import库或实现延迟导入的代码片段来完成。
- 通过添加
from __future__ import annotations
在每个文件的开始处来使类型注解延迟(参见PEP 563)。 - 如果某个导入只是为了在类型注解中使用,请将其移动到if TYPE_CHECKING块内部。
并且作为一般规则,在证明其缓慢之前不要优化任何东西。这就是这个工具存在的原因。
模块类型
对于每个报告的模块,该工具将显示以下类型之一
- root 是您基准测试的原模块(或其父模块之一)。
- project 是根模块的子模块。
- dependency 是项目中某个模块的直接依赖。
- transitive 是依赖项的依赖。