gpt4 book ai didi

python - 使用 item[n-1] + item[and] 内存的生成器

转载 作者:太空狗 更新时间:2023-10-30 00:17:29 25 4
gpt4 key购买 nike

我有一个 Python 3.x 程序可以处理几个大型文本文件,这些文件包含大量数据数组,这些数据偶尔会刷新我微不足道的工作站的内存限制。从一些基本的内存分析来看,似乎在使用生成器时,我的脚本气球用于保存连续元素的内存使用量是我预期的两倍。

我做了一个简单的独立示例来测试生成器,我在 Python 2.7、3.3 和 3.4 中得到了类似的结果。我的测试代码如下,memory_usage()this function from an SO question 的修改版本它使用 /proc/self/status 并在我观看时同意 topresource 可能是一种更跨平台的方法:

import sys, resource, gc, time

def biggen():
sizes = 1, 1, 10, 1, 1, 10, 10, 1, 1, 10, 10, 20, 1, 1, 20, 20, 1, 1
for size in sizes:
data = [1] * int(size * 1e6)
#time.sleep(1)
yield data

def consumer():
for data in biggen():
rusage = resource.getrusage(resource.RUSAGE_SELF)
peak_mb = rusage.ru_maxrss/1024.0
print('Peak: {0:6.1f} MB, Data Len: {1:6.1f} M'.format(
peak_mb, len(data)/1e6))
#print(memory_usage()) #

data = None # go
del data # away
gc.collect() # please.

# def memory_usage():
# """Memory usage of the current process, requires /proc/self/status"""
# # https://stackoverflow.com/a/898406/194586
# result = {'peak': 0, 'rss': 0}
# for line in open('/proc/self/status'):
# parts = line.split()
# key = parts[0][2:-1].lower()
# if key in result:
# result[key] = int(parts[1])/1024.0
# return 'Peak: {peak:6.1f} MB, Current: {rss:6.1f} MB'.format(**result)

print(sys.version)
consumer()

在实践中,我将处理来自这样一个生成器循环的数据,只保存我需要的,然后丢弃它。

当我运行上面的脚本时,两个大元素连续出现(数据大小可能变化很大),似乎 Python 在释放前一个元素之前先计算下一个元素,导致内存使用量增加一倍。

$ python genmem.py 
2.7.3 (default, Sep 26 2013, 20:08:41)
[GCC 4.6.3]
Peak: 7.9 MB, Data Len: 1.0 M
Peak: 11.5 MB, Data Len: 1.0 M
Peak: 45.8 MB, Data Len: 10.0 M
Peak: 45.9 MB, Data Len: 1.0 M
Peak: 45.9 MB, Data Len: 1.0 M
Peak: 45.9 MB, Data Len: 10.0 M
# ^^ not much different versus previous 10M-list
Peak: 80.2 MB, Data Len: 10.0 M
# ^^ same list size, but new memory peak at roughly twice the usage
Peak: 80.2 MB, Data Len: 1.0 M
Peak: 80.2 MB, Data Len: 1.0 M
Peak: 80.2 MB, Data Len: 10.0 M
Peak: 80.2 MB, Data Len: 10.0 M
Peak: 118.3 MB, Data Len: 20.0 M
# ^^ and again... (20+10)*x
Peak: 118.3 MB, Data Len: 1.0 M
Peak: 118.3 MB, Data Len: 1.0 M
Peak: 118.3 MB, Data Len: 20.0 M
Peak: 156.5 MB, Data Len: 20.0 M
# ^^ and again. (20+20)*x
Peak: 156.5 MB, Data Len: 1.0 M
Peak: 156.5 MB, Data Len: 1.0 M

疯狂的腰带和吊带和胶带方法 data = Nonedel datagc.collect() 什么都不做。

我很确定生成器本身不会在内存上加倍,否则它产生的单个大值会增加峰值使用量,并且在相同的迭代中出现了一个大对象;它只是大的连续对象。

如何保存我的内存?

最佳答案

问题出在生成器函数中;特别是在声明中:

    data = [1] * int(size * 1e6)

假设您在 data 变量中有旧内容。当你运行这个语句时,它首先计算结果,因此你在内存中有 2 个这样的数组;旧的和新的。只有这样,data 变量才会更改为指向新结构,并释放旧结构。尝试将迭代器函数修改为:

def biggen():
sizes = 1, 1, 10, 1, 1, 10, 10, 1, 1, 10, 10, 20, 1, 1, 20, 20, 1, 1
for size in sizes:
data = None
data = [1] * int(size * 1e6)
yield data

关于python - 使用 item[n-1] + item[and] 内存的生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21787099/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com