[英]How do I async pickle a lot of files with aiofiles?
我有一个我想写出的列表, data
,每个项目一个文件,如下所示:
for i,chunk in enumerate(data):
fname = ROOT / f'{i}.in'
with open(fname, "wb") as fout:
dill.dump(chunk, fout)
由于数据列表可能很长,而且我正在写入网络存储位置,因此我花了很多时间在 NFS 中来回等待迭代,如果可能,我想异步执行此操作。
我现在有一些基本上看起来像这样的东西:
import dill
import asyncio
import aiofiles
from pathlib import Path
ROOT = Path("/tmp/")
data = [str(i) for i in range(500)]
def serialize(data):
"""
Write my data out in serial
"""
for i,chunk in enumerate(data):
fname = ROOT / f'{i}.in'
print(fname)
with open(fname, "wb") as fout:
dill.dump(chunk, fout)
def aserialize(data):
"""
Same as above, but writes my data out asynchronously
"""
fnames = [ROOT / f'{i}.in' for i in range(len(data))]
chunks = data
async def write_file(i):
fname = fnames[i]
chunk = chunks[i]
print(fname)
async with aiofiles.open(fname, "wb") as fout:
print(f"written: {i}")
dill.dump(chunk, fout)
await fout.flush()
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*[write_file(i) for i in range(len(data))]))
现在,当我测试写入时,这看起来足够快,值得在我的 NFS 上使用:
# test 1
start = datetime.utcnow()
serialize(data)
end = datetime.utcnow()
print(end - start)
# >>> 0:02:04.204681
# test 3
start = datetime.utcnow()
aserialize(data)
end = datetime.utcnow()
print(end - start)
# >>> 0:00:27.048893
# faster is better.
但是当我实际 /de/-serialize 我写的数据时,我发现它可能很快,因为它没有写任何东西:
def deserialize(dat):
tmp = []
for i in range(len(dat)):
fname = ROOT / f'{i}.in'
with open(fname, "rb") as fin:
fo = dill.load(fin)
tmp.append(fo)
return tmp
serialize(data)
d2 = deserialize(data)
d2 == data
# True
很好,而:
aserialize(data)
d3 = deserialize(data)
>>> Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in deserialize
File "...python3.7/site-packages/dill/_dill.py", line 305, in load
obj = pik.load()
EOFError: Ran out of input
即异步写入的文件为空。 怪不得这么快。
如何将我的列表异步挖掘/腌制到文件中并让它们实际写入? 我想我需要以某种方式等待 dill.dump 吗? 我以为 fout.flush 会处理这个问题,但似乎不是。
我将行dill.dump(chunk, fout)
更改为await fout.write(dill.dumps(chunk))
并将数据写入文件并正确反序列化。 似乎dill.dump
仅适用于调用file.write
方法而没有await
关键字的常规同步文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.