Я создал пакет python для построения исходных топологий для моделирования. По сути, для создания таких топологий пользователь создает пул объектов, а затем добавляет в него другие объекты. В настоящее время, когда добавляется много объектов (> 100000), потребление памяти идет вверх. Я отслеживал это с помощью tracemallo c:
import tracemalloc
tracemalloc.start()
sn1 = tracemalloc.take_snapshot()
object_pool.add_objects(object_to_add, N = 100)
sn2 = tracemalloc.take_snapshot()
ts = sn2.compare_to(sn1, 'lineno')
for stat in ts[:10]: print(stat)
Это дает следующее:
<__array_function__ internals>:6: size=4932 KiB (+4932 KiB), count=200 (+200), average=24.7 KiB
/usr/lib/python3.7/copy.py:237: size=644 KiB (+644 KiB), count=4554 (+4554), average=145 B
/usr/lib/python3.7/copy.py:169: size=190 KiB (+190 KiB), count=1388 (+1388), average=140 B
/usr/lib/python3.7/copyreg.py:88: size=103 KiB (+103 KiB), count=1500 (+1500), average=70 B
Таким образом, нагрузка на основную память составляет __array_function__ internals
. Под капотом add_objects создает копию object_to_add и добавляет ее в пул. Эти объекты имеют тенденцию быть довольно сложными. Интересно, что изменение numpy с версии 1.17 до 1.18 уменьшило объем используемой памяти на __array_function__ internals
в 10 раз.
Мои вопросы: как работает __array_function__ internals
и как уменьшить количество памяти, используемой им? Является ли единственной возможностью уменьшить количество используемых numpy массивов?
РЕДАКТИРОВАТЬ: речь идет о пакете hoobas: https://bitbucket.org/NUaztec/hoobas/src/master/ Пул объектов является компоновщиком, а добавленные объекты являются композитами. Они содержат numpy массивы только для позиций (плавающие). Чтобы полностью воспроизвести поведение:
import hoobas
box = hoobas.SimulationDomain.EmptyCube(10.0)
object_to_add = hoobas.LinearChain.GenericPolymer(2)
object_pool = hoobas.Build.HOOMDBuilder(box)
object_pool.add_N_ext_obj(object_to_add, 100)