Python中的静态内存:循环中会创建变量的新实例吗?

17 投票
3 回答
12297 浏览
提问于 2025-04-16 01:40

我一直在运行一些Python脚本,这些脚本会多次调用一些函数,比如F1(x)和F2(x),它们的样子大概是这样的:

x = LoadData()

for j in range(N):
    y = F1(x[j])
    z[j] = F2(y)

    del y

SaveData(z)

如果我保留“del y”这一行,性能会快很多。但我不明白为什么会这样。如果我不使用“del y”,那么我的内存很快就会用完,只能使用虚拟内存,这样一来,速度就会变得非常慢。但是如果我使用“del y”,我就会不断地清空和重新分配y的内存。我希望y能够作为静态内存存在,并在每次调用F1(x)时重复使用这块内存。但从我观察的情况来看,这似乎并没有发生。

另外,不确定这是否相关,但我的数据是numpy数组。

3 个回答

0

对于非常大的数字N,使用xrange来代替range可以节省内存。另外,你可以把函数嵌套在一起,但我不确定这对你是否有帮助。: \

x = LoadData()

for j in xrange(N):
    z[j] = F2(F1(x[j]))

SaveData(z)

也许F1和F2在不必要地复制对象,最好的方法是就地处理,像这样:

x = LoadData()
for item in x:
    item.F1()
    item.F2()
SaveData(x)

抱歉,如果我的回答没有帮助

2

你想要做的事情在Python里有点特别——你想为y分配一块内存,然后把这块内存的地址传给F1(),这样F1()就可以在这块内存里更新y的值。这样做的好处是,F1()就不用自己去分配内存来存放新的y的值,而是直接在你自己定义的y的地址上进行修改(实际上,y并不是F1()计算出来的值,而是指向那个值的地址)。

关于在Python中如何通过引用传递变量,已经有相关的问题讨论了:如何通过引用传递变量?

17

如果不使用 del y,你可能会需要更多的内存。原因是每次循环时,y 都会保存上一次 F1 的结果,而在计算下一个结果的时候,这个旧的值仍然占用内存。

F1 计算完成后,y 会更新为新的值,这样之前的 F1 结果就可以被释放掉。

这意味着 F1 返回的对象会占用相当多的内存。

如果把循环展开来看前几次的执行,会是这样的:

y = F1(x[0])   # F1(x[0]) is calculated, then y is bound to it
z[j] = F2(y)
y = F1(x[1])   # y is still bound to F1(x[0]) while F1(x[1]) is computed
               # The memory for F1(X[0]) is finally freed when y is rebound
z[j] = F2(y)

如果你的情况正是这样,使用 del y 是个不错的解决办法。

撰写回答