gpt4 book ai didi

python - 减少运行时间、文件读取、每行的字符串操作和文件写入

转载 作者:太空宇宙 更新时间:2023-11-03 15:35:12 24 4
gpt4 key购买 nike

我正在编写一个脚本,该脚本从多个文件中读取所有行,在每个 block 的开头读取一个数字,并将该数字放在 block 的每一行前面,直到下一个数字,依此类推。之后,它将所有读取行写入单个 .csv 文件。

我正在阅读的文件如下所示:

13368:
2385003,4,2004-07-08
659432,3,2005-03-16
13369:
751812,2,2002-12-16
2625420,2,2004-05-25

输出文件应该是这样的:

13368,2385003,4,2004-07-08
13368,659432,3,2005-03-16
13369,751812,2,2002-12-16
13369,2625420,2,2004-05-25

目前我的脚本是这样的:

from asyncio import Semaphore, ensure_future, gather, run
import time

limit = 8

async def read(file_list):
tasks = list()
result = None

sem = Semaphore(limit)

for file in file_list:
task = ensure_future(read_bounded(file,sem))
tasks.append(task)

result = await gather(*tasks)

return result

async def read_bounded(file,sem):
async with sem:
return await read_one(file)

async def read_one(filename):
result = list()
with open(filename) as file:
dataList=[]
content = file.read().split(":")
file.close()
j=1
filmid=content[0]
append=result.append
while j<len(content):
for entry in content[j].split("\n"):
if len(entry)>10:
append("%s%s%s%s" % (filmid,",",entry,"\n"))
else:
if len(entry)>0:
filmid=entry
j+=1
return result

if __name__ == '__main__':
start=time.time()
write_append="w"
files = ['combined_data_1.txt', 'combined_data_2.txt', 'combined_data_3.txt', 'combined_data_4.txt']

res = run(read(files))

with open("output.csv",write_append) as outputFile:
for result in res:
outputFile.write(''.join(result))
outputFile.flush()
outputFile.close()
end=time.time()
print(end-start)

它的运行时间约为 135 秒(读取的 4 个文件各 500MB,输出文件有 2.3GB)。运行脚本需要大约 10GB 的 RAM。我认为这可能是一个问题。我认为创建所有行的列表需要最多的时间。我想减少这个程序的运行时间,但我是 python 的新手,不知道该怎么做。你能给我一些建议吗?

谢谢

编辑:

我在 cmd 中测量了以下命令的时间(我的计算机上只安装了 Windows,所以我希望使用等效的 cmd 命令):

顺序写入 NUL

timecmd "type combined_data_1.txt combined_data_2.txt combined_data_3.txt combined_data_4.txt  > NUL"

combined_data_1.txt


combined_data_2.txt


combined_data_3.txt


combined_data_4.txt

command took 0:1:25.87 (85.87s total)

顺序写入文件

timecmd "type combined_data_1.txt combined_data_2.txt combined_data_3.txt combined_data_4.txt  > test.csv"

combined_data_1.txt
combined_data_2.txt
combined_data_3.txt
combined_data_4.txt

command took 0:2:42.93 (162.93s total)

并行

timecmd "type combined_data_1.txt > NUL & type combined_data_2.txt > NUL & type combined_data_3.txt >NUL & type combined_data_4.txt  > NUL"
command took 0:1:25.51 (85.51s total)

最佳答案

在这种情况下,使用 asyncio 不会获得任何好处,原因有二:

  • asyncio 是单线程的,不并行处理(在 Python 中,neither can threads)
  • IO 调用访问文件系统,asyncio 不包括它——它主要是关于网络 IO

您没有正确使用 asyncio 的事实是您的 read_one 协程不包含单个 await。这意味着它永远不会暂停执行,并且它会在屈服于另一个协程之前运行完成。将其设为普通函数(并完全放弃 asyncio)会产生完全相同的结果。

这是脚本的重写版本,有以下更改:

  • 字节IO贯穿始终,为了效率
  • 遍历文件而不是一次加载所有文件
  • 顺序代码
import sys

def process(in_filename, outfile):
with open(in_filename, 'rb') as r:
for line in r:
if line.endswith(b':\n'):
prefix = line[:-2]
continue
outfile.write(b'%s,%s' % (prefix, line))

def main():
in_files = sys.argv[1:-1]
out_file = sys.argv[-1]
with open(out_file, 'wb') as out:
for fn in in_files:
process(fn, out)

if __name__ == '__main__':
main()

在我的机器和 Python 3.7 上,这个版本的性能约为 22 s/GiB,测试了四个随机生成的文件,每个文件 550 MiB。它的内存占用量可以忽略不计,因为它从不将整个文件加载到内存中。

该脚本在 Python 2.7 上运行时没有任何变化,时钟频率为 27 s/GiB。 Pypy (6.0.0) 运行速度更快,仅需 11 s/GiB。

理论上,使用 concurrent.futures 应该允许在一个线程中处理,而另一个线程正在等待 IO,但结果最终比最简单的顺序方法慢 .

关于python - 减少运行时间、文件读取、每行的字符串操作和文件写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55226823/

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