[英]Improving the efficiency (memory/time) of the following python code
我必须阅读大约300个文件才能与以下代码建立关联。 给定关联,我必须在内存中全部读取它们。
with util.open_input_file(f) as f_in:
for l in f_in:
w = l.split(',')
dfm = dk.to_key((idx, i, int(w[0]), int(w[1]))) <-- guaranteed to be unique for each line in file.
cands = w[2].split(':')
for cand in cands:
tmp_data.setdefault(cand, []).append(dfm)
然后我需要以这种格式写出上面的数据结构:
k1, v1:v2,v3....
k2, v2:v5,v6...
我使用以下代码:
# Sort / join values.
cand2dfm_data = {}
for k,v in tmp_data.items():
cand2dfm_data[k] = ':'.join(map(str, sorted(v, key=int)))
tmp_data = {}
# Write cand2dfm CSV file.
with util.open_output_file(cand2dfm_file) as f_out:
for k in sorted(cand2dfm_data.keys()):
f_out.write('%s,%s\n' % (k, cand2dfm_data[k]))
由于必须处理大量文件,因此我发现了两个问题:
用于存储tmp_data的内存很大。 在我的用例中,处理300个文件,它使用的是42GB。
写入CSV文件需要很长时间。 这是因为我在每个item()上调用write()(大约2.2M)。 此外,输出流使用gzip压缩程序来节省磁盘空间。
在我的用例中,数字保证为32位无符号。
题:
为了减少内存,我认为使用32位int存储数据会更好。 我应该使用ctypes.c_int()将值存储在dict()中(现在它们是字符串)还是有更好的方法?
为了加快写入速度,我应该先写入StringIO对象,然后将其转储到文件中,还是有更好的方法?
另外,也许有一种更好的方法可以完成上述逻辑而不读取内存中的所有内容?
很少的想法。
当前,您正在内存中多次复制数据。 您是第一次将其加载到tmp_data
,然后将所有内容复制到cand2dfm_data
,然后通过调用sorted(cand2dfm_data.keys())
创建键列表。
要减少内存使用量:
摆脱tmp_data
,解析并将数据直接写入cand2dfm_data
使cand2dfm_data
成为元组列表,而不是字典
使用cand2dfm_data.sort(...)
而不是sorted(cand2dfm_data)
以避免创建新列表
要加快处理速度:
将键转换为整数以提高排序性能(这也将减少内存使用)
一次将数据分块写入磁盘,例如一次100或500或1000条记录,这应该会稍微提高I \\ O性能
使用探查器查找其他性能瓶颈
如果通过上述优化,内存占用空间仍然太大,则可以考虑使用磁盘支持的存储来存储和排序临时数据,例如SQLite
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.