Python内存模型

时间:2009-06-29 18:12:55

标签: python arrays memory model

我有一个非常大的清单 假设我这样做(是的,我知道代码非常单调,但为了示例的缘故......):

n = (2**32)**2
for i in xrange(10**7)
  li[i] = n

工作正常。但是:

for i in xrange(10**7)
  li[i] = i**2

消耗大量内存。我不明白为什么会这样 - 存储大数字需要更多位,而在Java中,第二个选项确实更节省内存...

有没有人对此有解释?

4 个答案:

答案 0 :(得分:17)

答案 1 :(得分:5)

在第一个示例中,您存储的是相同的整数len(arr)次。因此python只需要将整数存储在内存中一次,并将其引用为len(arr)次。

在第二个示例中,您存储的是len(arr)不同的整数。现在python必须为len(arr)整数分配存储空间,并在每个len(arr)插槽中引用它们。

答案 2 :(得分:3)

您只有一个变量n,但您创建了许多i ** 2.

Python会使用引用。每次执行array[i] = n时,都会创建对n值的新引用。注意,不要把变量告诉价值。但是,在第二种情况下,当您执行array[i] = i**2时,您将创建一个新值,并引用此新值。这当然会占用更多的内存。

事实上,Python将继续重用相同的值,即使重新计算它也只是使用它。例如:

l = []
x = 2
for i in xrange(1000000):
    l.append(x*2)

通常不会使用比

更多的内存
l = []
x = 2
for i in xrange(1000000):
    l.append(x)

然而,在

的情况下
l = []
x = 2
for i in xrange(1000000):
    l.append(i)

i的每个值都会得到一个引用,因此与其他示例相比,会占用大量内存。

(Alex在术语中指出了一些混淆。在python中有一个叫做数组的模块。这些类型的数组存储整数值,而不是像Pythons普通列表对象这样的对象的引用,但在其他方面表现相同。但是从第一个开始示例使用的值不能存储在这样的数组中,这种情况不太可能。

相反,问题很可能是使用单词数组,因为它在许多其他语言中使用,这与Pythons列表类型相同。)

答案 3 :(得分:0)

在两个示例中,arr[i]都会引用对象,无论它是n还是i * 2的结果对象。

在第一个示例中,n已经定义,因此它只需要引用,但在第二个示例中,它必须评估i * 2,GC必须为此新结果对象分配空间,并且然后使用它的参考。