繁体   English   中英

使用稀疏数据的列表消耗的内存少于与numpy数组相同的数据

[英]List with sparse data consumes less memory then the same data as numpy array

我正在使用非常高维度的向量进行机器学习,并且正在考虑使用numpy来减少使用的内存量。 我运行一个快速测试,看看我可以使用numpy(1)(3)节省多少内存:

标准清单

import random
random.seed(0)
vector = [random.random() for i in xrange(2**27)]

Numpy数组

import numpy
import random
random.seed(0)
vector = numpy.fromiter((random.random() for i in xrange(2**27)), dtype=float)

内存使用情况(2)

Numpy array: 1054 MB
Standard list: 2594 MB

就像我预期的那样。

通过使用本机浮点数分配一个连续的内存块numpy只消耗标准列表正在使用的内存的大约一半。

因为我知道我的数据非常多,所以我使用稀疏数据进行了相同的测试。

标准清单

import random
random.seed(0)
vector = [random.random() if random.random() < 0.00001 else 0.0 for i in xrange(2 ** 27)]

Numpy数组

from numpy import fromiter
from random import random
random.seed(0)
vector = numpy.fromiter((random.random() if random.random() < 0.00001 else 0.0 for i in xrange(2 ** 27)), dtype=float)

内存使用情况(2)

Numpy array: 1054 MB
Standard list: 529 MB

现在突然间,python列表使用了numpy数组使用的内存量的一半! 为什么?

我能想到的一件事是,当python检测到它包含非常稀疏的数据时,它会动态切换到dict表示。 检查这可能会增加很多额外的运行时间开销,所以我真的不认为这是在继续。

笔记

  1. 我为每个测试开始了一个全新的python shell。
  2. 记忆用htop测量。
  3. 在32位Debian上运行。

Python列表只是Python对象的引用(指针)数组。 在CPython(通常的Python实现)中,列表稍微过度分配以使扩展更有效,但它永远不会转换为dict。 有关更多详细信息,请参阅源代码: 列出对象实现

在列表的稀疏版本中,您有许多指向单个int 0对象的指针。 这些指针占用32位= 4个字节,但你的numpy浮点肯定更大,可能是64位。

FWIW,为了使稀疏列表/数组测试更准确,你应该在两个版本中使用相同的种子调用random.seed(some_const) ,以便在Python列表和numpy数组中获得相同数量的零。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM