首页 > 解决方案 > Numpy/Scipy:每次迭代的内存消耗线性增加

问题描述

运行以下代码时:

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.8Gb!

我再次使用以下功能进行了测试:

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)

内存消耗线性增加到> 800Mb。

我有两个问题:

  1. 为什么在每种情况下内存消耗都会线性增加?每次迭代都没有声明新变量...

  2. 考虑到矩阵是稀疏的(只有 0.1 密度),为什么在第一个测试中内存消耗比第二个要高得多?

预先感谢您的回答!

标签: pythonnumpyscipy

解决方案


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)
  1. 我将这两个函数占用的内存差异归因于 numpy 数据结构比 scipy 更优化的事实。即它们占用的空间更少。

推荐阅读