为什么我的包占用这么多内存
Why Does My Package Take up so Much Memory
我正在研究 Ptera Software,一种开源空气动力学求解器。这是我分发的第一个包,我遇到了一些与内存管理相关的问题。
具体来说,导入我的包会占用大量内存。我上次检查时,它占用了大约 136 MB 的 RAM。 PyPI 列出包大小为 118 MB,这似乎也高得离谱。作为参考,NumPy 只有 87 MB。
起初,我以为我可能不小心在包中包含了一些大文件。所以我从 PyPI 下载了每个版本的 tar.gz 文件并解压缩了它们。 None 解压超过 1 MB。
这让我相信我导入需求的方式有问题。我的 REQUIREMENTS.txt 文件如下所示:
matplotlib >= 3.2.2, < 4.0.0
numpy >= 1.18.5, < 2.0.0
pyvista >= 0.29.0, < 1.0.0
scipy >= 1.5, < 2.0
numba >= 0.53, <1.0
也可能是我弄乱了 __init__.py 文件。它看起来像这样:
from pterasoftware import aerodynamics
from pterasoftware import airfoils
from pterasoftware import geometry
from pterasoftware import meshing
from pterasoftware import movement
from pterasoftware import operating_point
from pterasoftware import output
from pterasoftware import problems
from pterasoftware import steady_horseshoe_vortex_lattice_method
from pterasoftware import steady_ring_vortex_lattice_method
from pterasoftware import unsteady_ring_vortex_lattice_method
目录结构如下:
├───pterasoftware
│ ├───airfoils
│ │ └───naca0012.dat
│ ├───__init__.py
│ ├───aerodynamics.py
│ ├───geometry.py
│ ├───meshing.py
│ ├───movement.py
│ ├───operating_point.py
│ ├───output.py
│ ├───problems.py
│ ├───steady_horsehoe_vortex_lattice_method.py
│ ├───steady_ring_vortex_lattice_method.py
│ └───unsteady_ring_vortex_lattice_method.py
我知道导入 numpy、matplotlib 和 scipy 等大型包可能会占用大量内存。但是,我知道有很多使用这些资源的包,导入这些资源不会占用将近 136 MB 的空间。我在这里错过了什么?
这是我用来测试导入包时分配的内存的代码:
from memory_profiler import profile
@profile
def find_import_memory_usage():
import pterasoftware as ps
if __name__ == "__main__":
find_import_memory_usage()
参见Importing a python module takes too much memory。导入模块需要内存来存储字节码(即 .pyc
文件)以及存储引用对象的编译形式。
那么,分配所有这些内存到底是为了什么?
我们可以通过 运行 您的内存分析器检查是否为您的程序包或您的依赖项分配了内存。我们会先导入你的包的依赖,看看它们占用了多少内存。
由于下次导入这些库时不会分配内存(您可以自己尝试),因此当我们导入您的包时,我们只会看到该包的内存使用情况,而不会看到它的依赖项。
from memory_profiler import profile
@profile
def find_import_memory_usage():
import matplotlib
import numpy
import pyvista
import scipy
import numba
import copy
import pterasoftware
这给了我(在 Windows 10 上使用股票 Python 3.7.6):
Line # Mem usage Increment Occurences Line Contents
============================================================
10 18.3 MiB 18.3 MiB 1 @profile
11 def find_import_memory_usage():
12 34.3 MiB 16.0 MiB 1 import matplotlib
13 34.3 MiB 0.0 MiB 1 import numpy
14 96.6 MiB 62.2 MiB 1 import pyvista
15 101.1 MiB 4.6 MiB 1 import scipy
16 137.3 MiB 36.2 MiB 1 import numba
17 137.3 MiB 0.0 MiB 1 import copy
18 174.6 MiB 37.3 MiB 1 import pterasoftware
你的包只用了37.3MiB,合理多了。 您的依赖项使用 119 MiB,而 Pyvista 是一个特别昂贵的导入。而当使用numpy时,会要求.
有 ways to reduce the memory requirements 个您自己的包(有些是以牺牲可读性为代价的,有些只是很好的实践,有些在使用像 Numba 这样的即时编译器时可能根本没有帮助) ,但是如果你想减少依赖项占用的内存,那么你可能只需要选择不同的依赖项,或者在最坏的情况下,修改它们的代码以将它们拆分为仅项目需要的组件,如果它们其他组件包含大量未使用的开销。
我正在研究 Ptera Software,一种开源空气动力学求解器。这是我分发的第一个包,我遇到了一些与内存管理相关的问题。
具体来说,导入我的包会占用大量内存。我上次检查时,它占用了大约 136 MB 的 RAM。 PyPI 列出包大小为 118 MB,这似乎也高得离谱。作为参考,NumPy 只有 87 MB。
起初,我以为我可能不小心在包中包含了一些大文件。所以我从 PyPI 下载了每个版本的 tar.gz 文件并解压缩了它们。 None 解压超过 1 MB。
这让我相信我导入需求的方式有问题。我的 REQUIREMENTS.txt 文件如下所示:
matplotlib >= 3.2.2, < 4.0.0
numpy >= 1.18.5, < 2.0.0
pyvista >= 0.29.0, < 1.0.0
scipy >= 1.5, < 2.0
numba >= 0.53, <1.0
也可能是我弄乱了 __init__.py 文件。它看起来像这样:
from pterasoftware import aerodynamics
from pterasoftware import airfoils
from pterasoftware import geometry
from pterasoftware import meshing
from pterasoftware import movement
from pterasoftware import operating_point
from pterasoftware import output
from pterasoftware import problems
from pterasoftware import steady_horseshoe_vortex_lattice_method
from pterasoftware import steady_ring_vortex_lattice_method
from pterasoftware import unsteady_ring_vortex_lattice_method
目录结构如下:
├───pterasoftware
│ ├───airfoils
│ │ └───naca0012.dat
│ ├───__init__.py
│ ├───aerodynamics.py
│ ├───geometry.py
│ ├───meshing.py
│ ├───movement.py
│ ├───operating_point.py
│ ├───output.py
│ ├───problems.py
│ ├───steady_horsehoe_vortex_lattice_method.py
│ ├───steady_ring_vortex_lattice_method.py
│ └───unsteady_ring_vortex_lattice_method.py
我知道导入 numpy、matplotlib 和 scipy 等大型包可能会占用大量内存。但是,我知道有很多使用这些资源的包,导入这些资源不会占用将近 136 MB 的空间。我在这里错过了什么?
这是我用来测试导入包时分配的内存的代码:
from memory_profiler import profile
@profile
def find_import_memory_usage():
import pterasoftware as ps
if __name__ == "__main__":
find_import_memory_usage()
参见Importing a python module takes too much memory。导入模块需要内存来存储字节码(即 .pyc
文件)以及存储引用对象的编译形式。
那么,分配所有这些内存到底是为了什么?
我们可以通过 运行 您的内存分析器检查是否为您的程序包或您的依赖项分配了内存。我们会先导入你的包的依赖,看看它们占用了多少内存。
由于下次导入这些库时不会分配内存(您可以自己尝试),因此当我们导入您的包时,我们只会看到该包的内存使用情况,而不会看到它的依赖项。
from memory_profiler import profile
@profile
def find_import_memory_usage():
import matplotlib
import numpy
import pyvista
import scipy
import numba
import copy
import pterasoftware
这给了我(在 Windows 10 上使用股票 Python 3.7.6):
Line # Mem usage Increment Occurences Line Contents
============================================================
10 18.3 MiB 18.3 MiB 1 @profile
11 def find_import_memory_usage():
12 34.3 MiB 16.0 MiB 1 import matplotlib
13 34.3 MiB 0.0 MiB 1 import numpy
14 96.6 MiB 62.2 MiB 1 import pyvista
15 101.1 MiB 4.6 MiB 1 import scipy
16 137.3 MiB 36.2 MiB 1 import numba
17 137.3 MiB 0.0 MiB 1 import copy
18 174.6 MiB 37.3 MiB 1 import pterasoftware
你的包只用了37.3MiB,合理多了。 您的依赖项使用 119 MiB,而 Pyvista 是一个特别昂贵的导入。而当使用numpy时,会要求
有 ways to reduce the memory requirements 个您自己的包(有些是以牺牲可读性为代价的,有些只是很好的实践,有些在使用像 Numba 这样的即时编译器时可能根本没有帮助) ,但是如果你想减少依赖项占用的内存,那么你可能只需要选择不同的依赖项,或者在最坏的情况下,修改它们的代码以将它们拆分为仅项目需要的组件,如果它们其他组件包含大量未使用的开销。