Numpy / Scipy: потребление памяти увеличивается линейно за одну итерацию - PullRequest
3 голосов
/ 03 октября 2019

При запуске следующего кода:

import numpy as np
import scipy.sparse
import time

def test():
    m = 10000
    n = 10000 
    for i in range(5):
        A = scipy.sparse.random(m, n, density=0.1, format='csr')
        x = np.random.randn(n)
        Ax = A.dot(x)
        time.sleep(2)

if __name__ == "__main__":
    test()

Я заметил, что потребление памяти линейно увеличилось до> 4,8 ГБ!

Я снова протестировал со следующей функцией:

def test2():
    m = 10000
    n = 10000
    for i in range(5):
        print(i)
        A = np.random.rand(m, n)
        x = np.random.randn(A.shape[1])
        Ax = A.dot(x)
        time.sleep(2)

Потребление памяти линейно увеличилось до> 800 МБ.

У меня есть два вопроса:

  1. Почему потребление памяти линейно увеличивается в каждом случае? На каждой итерации не объявлялись новые переменные ...

  2. Почему в первом тесте потребление памяти намного выше, чем во втором, учитывая, что матрицы являются разреженными (всего 0,1плотность)?

Заранее благодарю за ответы!

1 Ответ

1 голос
/ 03 октября 2019

1. Поскольку все ваши объявления переменных находятся внутри не вложенного for... цикла , они повторяются в каждой итерации, причем каждая строка вносит различные линейные приращения (O(n)) к общему использованию памяти. Кроме того, поскольку нет операции по освобождению памяти, такой как delete operation после итерации, использование памяти увеличивается с предыдущих итераций. Ниже приведены результаты профиля памяти def test()

|Line|  |Mem usage|    |Increment|   |Line Contents|
-----------------------------------------------------
     5   1844.9 MiB   1844.9 MiB   def test():
     6   1844.9 MiB      0.0 MiB       m = 10000
     7   1844.9 MiB      0.0 MiB       n = 10000 
     8   4518.7 MiB      0.0 MiB       for i in range(5):
     9   4518.7 MiB    763.7 MiB           A = scipy.sparse.random(m, n, density=0.1, format='csr')
    10   4518.7 MiB      0.0 MiB           x = np.random.randn(n)
    11   4518.7 MiB      0.0 MiB           Ax = A.dot(x)
    12   4518.7 MiB      0.0 MiB           time.sleep(2)
Я бы объяснил разницу в памяти, занимаемой этими двумя функциями, тем фактом, что структуры с пустыми данными более оптимизированы по сравнению с scipy. То есть они занимают меньше места.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...