Numpy 的位运算和垃圾收集器
Numpy's bitwise operations and garbage collector
我正在使用 numpy 的按位函数并尝试减少脚本的内存占用:
import os, gc, psutil, resource, numpy as np
def print_memory():
print(
"Max %.2f MB - Current %.2f MB"
% (
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024,
psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024,
)
)
print_memory()
data = np.arange(1000000, dtype=np.uint64) # About 7.63 MB
result = np.zeros(data.size, dtype=np.uint64) # More 7.63 MB
a = np.right_shift(data, 50)
b = np.left_shift(data, 39)
result = np.bitwise_xor(data, np.bitwise_xor(np.bitwise_or(a, b), 1))
del a, b
gc.collect()
print_memory()
输出:
Max 28.05 MB - Current 28.05 MB
Max 66.71 MB - Current 43.90 MB
这是有道理的。最后我们有 43.9 MB − 28.05 MB = 15.85 MB
,这是我的两个 7.63 MB
数组的大小。使用的最大内存相同,66.71 MB − 28.05 MB = 38.66 MB
,这是我的两个 7.63 MB
数组(data
和 result
),以及它们保存在变量 a
和b
,np.bitwise_or(a, b)
给出的结果。即 7.63 MB * 5 = 38.15 MB
,几乎是 38.66 MB
.
以下更改及其结果引起了我的兴趣。
import os, gc, psutil, resource, numpy as np
def print_memory():
print(
"Max %.2f MB - Current %.2f MB"
% (
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024,
psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024,
)
)
print_memory()
data = np.arange(1000000, dtype=np.uint64) # About 7.63 MB
result = np.zeros(data.size, dtype=np.uint64) # More 7.63 MB
result = np.bitwise_xor(
data,
np.bitwise_xor(np.bitwise_or(np.right_shift(data, 50), np.left_shift(data, 39)), 1),
)
gc.collect()
print_memory()
产生:
Max 28.14 MB - Current 28.14 MB
Max 58.98 MB - Current 51.52 MB
我假设 numpy/python 能够以某种方式将最大内存占用量从输入数组的 5 倍减少到 4 倍,这是受欢迎的。但是,为什么它以 51.52 MB − 28.14 MB = 23.38 MB
结尾,这几乎是三个大小为 7.63 MB
的数组?第三个 7.63 MB
数组来自哪里?是否是垃圾收集器未收集到的内部操作的结果?最终,我该如何解决这个问题并获得两全其美:减少第二个脚本提供的最大内存使用量,并像第一个脚本一样在最后“正确”使用内存?
在我的机器上,你的两种方法给出了以下足迹:
方法一:
print_memory()
data = np.arange(1000000, dtype=np.uint64) # About 7.63 MB
result = np.zeros(data.size, dtype=np.uint64) # More 7.63 MB
a = np.right_shift(data, 50)
b = np.left_shift(data, 39)
result = np.bitwise_xor(data, np.bitwise_xor(np.bitwise_or(a, b), 1))
del a, b
gc.collect()
print_memory()
这会产生:
Max 29.96 MB - Current 29.96 MB
Max 68.26 MB - Current 45.40 MB
方法二:
print_memory()
data = np.arange(1000000, dtype=np.uint64) # About 7.63 MB
result = np.zeros(data.size, dtype=np.uint64) # More 7.63 MB
result = np.bitwise_xor(
data,
np.bitwise_xor(np.bitwise_or(np.right_shift(data, 50), np.left_shift(data, 39)), 1),
)
gc.collect()
print_memory()
这会产生:
Max 29.88 MB - Current 29.88 MB
Max 60.46 MB - Current 52.95 MB
方法三:
现在寻找可能的解决方案。如果按以下方式编写操作,似乎可以两全其美:
print_memory()
data = np.arange(1000000, dtype=np.uint64) # About 7.63 MB
result = np.zeros(data.size, dtype=np.uint64) # More 7.63 MB
np.bitwise_or(np.right_shift(data, 50), np.left_shift(data, 39), out = result)
np.bitwise_xor(result, 1, out = result)
np.bitwise_xor(data, result, out = result)
gc.collect()
print_memory()
这会产生:
Max 29.96 MB - Current 29.96 MB
Max 60.41 MB - Current 45.41 MB
现在我不太确定为什么会这样。但是,我注意到这些按位运算支持 out
参数;我想知道设置 out = result
是否有助于 numpy 在每个步骤中重用相同的内存位置,从而以某种方式提高内存效率。好像有帮助。
使用tracemalloc
,您可以验证两次执行后只剩下两次分配。问题可能是 7MB 不足以让 OS 或标准库实际释放内存,但 free
已被调用。
见代码A:
import tracemalloc
import os, gc, psutil, resource, numpy as np
def print_memory():
print(
"Max %.2f MB - Current %.2f MB"
% (
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024,
psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024,
)
)
tracemalloc.start()
# ... start your application ...
snapshot1 = tracemalloc.take_snapshot()
print_memory()
data = np.arange(1000000, dtype=np.uint64) # About 7.63 MB
result = np.zeros(data.size, dtype=np.uint64) # More 7.63 MB
a = np.right_shift(data, 50)
b = np.left_shift(data, 39)
result = np.bitwise_xor(data, np.bitwise_xor(np.bitwise_or(a, b), 1))
del a, b
gc.collect()
print_memory()
snapshot2 = tracemalloc.take_snapshot()
top_stats = snapshot2.compare_to(snapshot1, 'lineno')
print("[ Top 10 differences ]")
for stat in top_stats[:10]:
print(stat)
产生:
Max 27.09 MB - Current 27.09 MB
Max 65.30 MB - Current 42.52 MB
[ Top 10 differences ]
main.py:27: size=7813 KiB (+7813 KiB), count=4 (+4), average=1953 KiB
main.py:21: size=7813 KiB (+7813 KiB), count=3 (+3), average=2604 KiB
/usr/lib/python3/dist-packages/psutil/__init__.py:699: size=816 B (+816 B), count=3 (+3), average=272 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1390: size=720 B (+720 B), count=3 (+3), average=240 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1597: size=648 B (+648 B), count=2 (+2), average=324 B
/usr/lib/python3/dist-packages/psutil/__init__.py:365: size=576 B (+576 B), count=1 (+1), average=576 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:187: size=520 B (+520 B), count=6 (+6), average=87 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1596: size=456 B (+456 B), count=1 (+1), average=456 B
/usr/lib/python3/dist-packages/psutil/_common.py:337: size=424 B (+424 B), count=1 (+1), average=424 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1429: size=376 B (+376 B), count=4 (+4), average=94 B
如您所见,只剩下两个 7MB 的分配。
见代码 B:
import tracemalloc
import os, gc, psutil, resource, numpy as np
def print_memory():
print(
"Max %.2f MB - Current %.2f MB"
% (
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024,
psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024,
)
)
tracemalloc.start()
# ... start your application ...
snapshot1 = tracemalloc.take_snapshot()
print_memory()
data = np.arange(1000000, dtype=np.uint64) # About 7.63 MB
result = np.zeros(data.size, dtype=np.uint64) # More 7.63 MB
result = np.bitwise_xor(
data,
np.bitwise_xor(np.bitwise_or(np.right_shift(data, 50), np.left_shift(data, 39)), 1),
)
gc.collect()
print_memory()
snapshot2 = tracemalloc.take_snapshot()
top_stats = snapshot2.compare_to(snapshot1, 'lineno')
print("[ Top 10 differences ]")
for stat in top_stats[:10]:
print(stat)
这会产生:
Max 27.08 MB - Current 27.08 MB
Max 57.55 MB - Current 50.14 MB
[ Top 10 differences ]
main2.py:26: size=7813 KiB (+7813 KiB), count=6 (+6), average=1302 KiB
main2.py:21: size=7813 KiB (+7813 KiB), count=3 (+3), average=2604 KiB
/usr/lib/python3/dist-packages/psutil/__init__.py:699: size=816 B (+816 B), count=3 (+3), average=272 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1390: size=720 B (+720 B), count=3 (+3), average=240 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1597: size=648 B (+648 B), count=2 (+2), average=324 B
/usr/lib/python3/dist-packages/psutil/__init__.py:365: size=576 B (+576 B), count=1 (+1), average=576 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:187: size=520 B (+520 B), count=6 (+6), average=87 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1596: size=456 B (+456 B), count=1 (+1), average=456 B
/usr/lib/python3/dist-packages/psutil/_common.py:337: size=424 B (+424 B), count=1 (+1), average=424 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1429: size=376 B (+376 B), count=4 (+4), average=94 B
也只剩下两个 7MB 的分配。
强制 OS 和 stdlib 实际释放内存的一种方法是使用大量内存,从而触发释放机制。例如对于 76MB,你得到预期的结果:
代码 A,data = np.arange(10000000, dtype=np.uint64) # About 76.3 MB
给出:
Max 26.93 MB - Current 26.93 MB
Max 408.54 MB - Current 179.69 MB
[ Top 10 differences ]
main.py:27: size=76.3 MiB (+76.3 MiB), count=4 (+4), average=19.1 MiB
main.py:21: size=76.3 MiB (+76.3 MiB), count=3 (+3), average=25.4 MiB
/usr/lib/python3/dist-packages/psutil/__init__.py:699: size=816 B (+816 B), count=3 (+3), average=272 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1390: size=720 B (+720 B), count=3 (+3), average=240 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1597: size=648 B (+648 B), count=2 (+2), average=324 B
/usr/lib/python3/dist-packages/psutil/__init__.py:365: size=576 B (+576 B), count=1 (+1), average=576 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:187: size=520 B (+520 B), count=6 (+6), average=87 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1596: size=456 B (+456 B), count=1 (+1), average=456 B
/usr/lib/python3/dist-packages/psutil/_common.py:337: size=424 B (+424 B), count=1 (+1), average=424 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1429: size=376 B (+376 B), count=4 (+4), average=94 B
代码 B 与 data = np.arange(10000000, dtype=np.uint64) # About 76.3 MB
给出:
Max 27.13 MB - Current 27.13 MB
Max 332.43 MB - Current 179.89 MB
[ Top 10 differences ]
main2.py:26: size=76.3 MiB (+76.3 MiB), count=6 (+6), average=12.7 MiB
main2.py:21: size=76.3 MiB (+76.3 MiB), count=3 (+3), average=25.4 MiB
/usr/lib/python3/dist-packages/psutil/__init__.py:699: size=816 B (+816 B), count=3 (+3), average=272 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1390: size=720 B (+720 B), count=3 (+3), average=240 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1597: size=648 B (+648 B), count=2 (+2), average=324 B
/usr/lib/python3/dist-packages/psutil/__init__.py:365: size=576 B (+576 B), count=1 (+1), average=576 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:187: size=520 B (+520 B), count=6 (+6), average=87 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1596: size=456 B (+456 B), count=1 (+1), average=456 B
/usr/lib/python3/dist-packages/psutil/_common.py:337: size=424 B (+424 B), count=1 (+1), average=424 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1429: size=376 B (+376 B), count=4 (+4), average=94 B
我正在使用 numpy 的按位函数并尝试减少脚本的内存占用:
import os, gc, psutil, resource, numpy as np
def print_memory():
print(
"Max %.2f MB - Current %.2f MB"
% (
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024,
psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024,
)
)
print_memory()
data = np.arange(1000000, dtype=np.uint64) # About 7.63 MB
result = np.zeros(data.size, dtype=np.uint64) # More 7.63 MB
a = np.right_shift(data, 50)
b = np.left_shift(data, 39)
result = np.bitwise_xor(data, np.bitwise_xor(np.bitwise_or(a, b), 1))
del a, b
gc.collect()
print_memory()
输出:
Max 28.05 MB - Current 28.05 MB
Max 66.71 MB - Current 43.90 MB
这是有道理的。最后我们有 43.9 MB − 28.05 MB = 15.85 MB
,这是我的两个 7.63 MB
数组的大小。使用的最大内存相同,66.71 MB − 28.05 MB = 38.66 MB
,这是我的两个 7.63 MB
数组(data
和 result
),以及它们保存在变量 a
和b
,np.bitwise_or(a, b)
给出的结果。即 7.63 MB * 5 = 38.15 MB
,几乎是 38.66 MB
.
以下更改及其结果引起了我的兴趣。
import os, gc, psutil, resource, numpy as np
def print_memory():
print(
"Max %.2f MB - Current %.2f MB"
% (
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024,
psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024,
)
)
print_memory()
data = np.arange(1000000, dtype=np.uint64) # About 7.63 MB
result = np.zeros(data.size, dtype=np.uint64) # More 7.63 MB
result = np.bitwise_xor(
data,
np.bitwise_xor(np.bitwise_or(np.right_shift(data, 50), np.left_shift(data, 39)), 1),
)
gc.collect()
print_memory()
产生:
Max 28.14 MB - Current 28.14 MB
Max 58.98 MB - Current 51.52 MB
我假设 numpy/python 能够以某种方式将最大内存占用量从输入数组的 5 倍减少到 4 倍,这是受欢迎的。但是,为什么它以 51.52 MB − 28.14 MB = 23.38 MB
结尾,这几乎是三个大小为 7.63 MB
的数组?第三个 7.63 MB
数组来自哪里?是否是垃圾收集器未收集到的内部操作的结果?最终,我该如何解决这个问题并获得两全其美:减少第二个脚本提供的最大内存使用量,并像第一个脚本一样在最后“正确”使用内存?
在我的机器上,你的两种方法给出了以下足迹:
方法一:
print_memory()
data = np.arange(1000000, dtype=np.uint64) # About 7.63 MB
result = np.zeros(data.size, dtype=np.uint64) # More 7.63 MB
a = np.right_shift(data, 50)
b = np.left_shift(data, 39)
result = np.bitwise_xor(data, np.bitwise_xor(np.bitwise_or(a, b), 1))
del a, b
gc.collect()
print_memory()
这会产生:
Max 29.96 MB - Current 29.96 MB
Max 68.26 MB - Current 45.40 MB
方法二:
print_memory()
data = np.arange(1000000, dtype=np.uint64) # About 7.63 MB
result = np.zeros(data.size, dtype=np.uint64) # More 7.63 MB
result = np.bitwise_xor(
data,
np.bitwise_xor(np.bitwise_or(np.right_shift(data, 50), np.left_shift(data, 39)), 1),
)
gc.collect()
print_memory()
这会产生:
Max 29.88 MB - Current 29.88 MB
Max 60.46 MB - Current 52.95 MB
方法三:
现在寻找可能的解决方案。如果按以下方式编写操作,似乎可以两全其美:
print_memory()
data = np.arange(1000000, dtype=np.uint64) # About 7.63 MB
result = np.zeros(data.size, dtype=np.uint64) # More 7.63 MB
np.bitwise_or(np.right_shift(data, 50), np.left_shift(data, 39), out = result)
np.bitwise_xor(result, 1, out = result)
np.bitwise_xor(data, result, out = result)
gc.collect()
print_memory()
这会产生:
Max 29.96 MB - Current 29.96 MB
Max 60.41 MB - Current 45.41 MB
现在我不太确定为什么会这样。但是,我注意到这些按位运算支持 out
参数;我想知道设置 out = result
是否有助于 numpy 在每个步骤中重用相同的内存位置,从而以某种方式提高内存效率。好像有帮助。
使用tracemalloc
,您可以验证两次执行后只剩下两次分配。问题可能是 7MB 不足以让 OS 或标准库实际释放内存,但 free
已被调用。
见代码A:
import tracemalloc
import os, gc, psutil, resource, numpy as np
def print_memory():
print(
"Max %.2f MB - Current %.2f MB"
% (
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024,
psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024,
)
)
tracemalloc.start()
# ... start your application ...
snapshot1 = tracemalloc.take_snapshot()
print_memory()
data = np.arange(1000000, dtype=np.uint64) # About 7.63 MB
result = np.zeros(data.size, dtype=np.uint64) # More 7.63 MB
a = np.right_shift(data, 50)
b = np.left_shift(data, 39)
result = np.bitwise_xor(data, np.bitwise_xor(np.bitwise_or(a, b), 1))
del a, b
gc.collect()
print_memory()
snapshot2 = tracemalloc.take_snapshot()
top_stats = snapshot2.compare_to(snapshot1, 'lineno')
print("[ Top 10 differences ]")
for stat in top_stats[:10]:
print(stat)
产生:
Max 27.09 MB - Current 27.09 MB
Max 65.30 MB - Current 42.52 MB
[ Top 10 differences ]
main.py:27: size=7813 KiB (+7813 KiB), count=4 (+4), average=1953 KiB
main.py:21: size=7813 KiB (+7813 KiB), count=3 (+3), average=2604 KiB
/usr/lib/python3/dist-packages/psutil/__init__.py:699: size=816 B (+816 B), count=3 (+3), average=272 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1390: size=720 B (+720 B), count=3 (+3), average=240 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1597: size=648 B (+648 B), count=2 (+2), average=324 B
/usr/lib/python3/dist-packages/psutil/__init__.py:365: size=576 B (+576 B), count=1 (+1), average=576 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:187: size=520 B (+520 B), count=6 (+6), average=87 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1596: size=456 B (+456 B), count=1 (+1), average=456 B
/usr/lib/python3/dist-packages/psutil/_common.py:337: size=424 B (+424 B), count=1 (+1), average=424 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1429: size=376 B (+376 B), count=4 (+4), average=94 B
如您所见,只剩下两个 7MB 的分配。
见代码 B:
import tracemalloc
import os, gc, psutil, resource, numpy as np
def print_memory():
print(
"Max %.2f MB - Current %.2f MB"
% (
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024,
psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024,
)
)
tracemalloc.start()
# ... start your application ...
snapshot1 = tracemalloc.take_snapshot()
print_memory()
data = np.arange(1000000, dtype=np.uint64) # About 7.63 MB
result = np.zeros(data.size, dtype=np.uint64) # More 7.63 MB
result = np.bitwise_xor(
data,
np.bitwise_xor(np.bitwise_or(np.right_shift(data, 50), np.left_shift(data, 39)), 1),
)
gc.collect()
print_memory()
snapshot2 = tracemalloc.take_snapshot()
top_stats = snapshot2.compare_to(snapshot1, 'lineno')
print("[ Top 10 differences ]")
for stat in top_stats[:10]:
print(stat)
这会产生:
Max 27.08 MB - Current 27.08 MB
Max 57.55 MB - Current 50.14 MB
[ Top 10 differences ]
main2.py:26: size=7813 KiB (+7813 KiB), count=6 (+6), average=1302 KiB
main2.py:21: size=7813 KiB (+7813 KiB), count=3 (+3), average=2604 KiB
/usr/lib/python3/dist-packages/psutil/__init__.py:699: size=816 B (+816 B), count=3 (+3), average=272 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1390: size=720 B (+720 B), count=3 (+3), average=240 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1597: size=648 B (+648 B), count=2 (+2), average=324 B
/usr/lib/python3/dist-packages/psutil/__init__.py:365: size=576 B (+576 B), count=1 (+1), average=576 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:187: size=520 B (+520 B), count=6 (+6), average=87 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1596: size=456 B (+456 B), count=1 (+1), average=456 B
/usr/lib/python3/dist-packages/psutil/_common.py:337: size=424 B (+424 B), count=1 (+1), average=424 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1429: size=376 B (+376 B), count=4 (+4), average=94 B
也只剩下两个 7MB 的分配。
强制 OS 和 stdlib 实际释放内存的一种方法是使用大量内存,从而触发释放机制。例如对于 76MB,你得到预期的结果:
代码 A,data = np.arange(10000000, dtype=np.uint64) # About 76.3 MB
给出:
Max 26.93 MB - Current 26.93 MB
Max 408.54 MB - Current 179.69 MB
[ Top 10 differences ]
main.py:27: size=76.3 MiB (+76.3 MiB), count=4 (+4), average=19.1 MiB
main.py:21: size=76.3 MiB (+76.3 MiB), count=3 (+3), average=25.4 MiB
/usr/lib/python3/dist-packages/psutil/__init__.py:699: size=816 B (+816 B), count=3 (+3), average=272 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1390: size=720 B (+720 B), count=3 (+3), average=240 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1597: size=648 B (+648 B), count=2 (+2), average=324 B
/usr/lib/python3/dist-packages/psutil/__init__.py:365: size=576 B (+576 B), count=1 (+1), average=576 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:187: size=520 B (+520 B), count=6 (+6), average=87 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1596: size=456 B (+456 B), count=1 (+1), average=456 B
/usr/lib/python3/dist-packages/psutil/_common.py:337: size=424 B (+424 B), count=1 (+1), average=424 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1429: size=376 B (+376 B), count=4 (+4), average=94 B
代码 B 与 data = np.arange(10000000, dtype=np.uint64) # About 76.3 MB
给出:
Max 27.13 MB - Current 27.13 MB
Max 332.43 MB - Current 179.89 MB
[ Top 10 differences ]
main2.py:26: size=76.3 MiB (+76.3 MiB), count=6 (+6), average=12.7 MiB
main2.py:21: size=76.3 MiB (+76.3 MiB), count=3 (+3), average=25.4 MiB
/usr/lib/python3/dist-packages/psutil/__init__.py:699: size=816 B (+816 B), count=3 (+3), average=272 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1390: size=720 B (+720 B), count=3 (+3), average=240 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1597: size=648 B (+648 B), count=2 (+2), average=324 B
/usr/lib/python3/dist-packages/psutil/__init__.py:365: size=576 B (+576 B), count=1 (+1), average=576 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:187: size=520 B (+520 B), count=6 (+6), average=87 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1596: size=456 B (+456 B), count=1 (+1), average=456 B
/usr/lib/python3/dist-packages/psutil/_common.py:337: size=424 B (+424 B), count=1 (+1), average=424 B
/usr/lib/python3/dist-packages/psutil/_pslinux.py:1429: size=376 B (+376 B), count=4 (+4), average=94 B