我正在写一个脚本,它读取一个文件夹中的文件(每个文件夹的大小从20 MB到100 MB不等),修改每行中的一些数据,然后写回文件的副本。
with open(inputPath, 'r+') as myRead:
my_list = myRead.readlines()
new_my_list = clean_data(my_list)
with open(outPath, 'w+') as myWrite:
tempT = time.time()
myWrite.writelines('\n'.join(new_my_list) + '\n')
print(time.time() - tempT)
print(inputPath, 'Cleaning Complete.')
在用一个90mb文件(大约900000行)运行此代码时,它打印140秒作为写入文件所需的时间。在这里我使用了writelines()
。所以我寻找了不同的方法来提高文件写入速度,在我阅读的大多数文章中,它都说write()
和writelines()
不应该显示任何差异,因为我正在编写一个连接字符串。我还检查了所花费的时间,仅用于以下语句:
new_string = '\n'.join(new_my_list) + '\n'
它只花了0.4秒,所以花费的大量时间并不是因为创建了列表。
为了尝试write()
我尝试了以下代码:
with open(inputPath, 'r+') as myRead:
my_list = myRead.readlines()
new_my_list = clean_data(my_list)
with open(outPath, 'w+') as myWrite:
tempT = time.time()
myWrite.write('\n'.join(new_my_list) + '\n')
print(time.time() - tempT)
print(inputPath, 'Cleaning Complete.')
打印了2.5秒。为什么即使是相同的数据,write()
和writelines()
的文件写入时间有如此大的差异?这是正常行为还是我的代码有问题?两种情况下的输出文件似乎都是相同的,所以我知道数据不会丢失。
“write(arg)”方法需要字符串作为其参数。所以一旦它调用,它就会直接写。这就是它更快的原因。 如果您使用的是
writelines()
方法,则它需要字符串列表作为迭代器。因此,即使您正在向writelines
发送数据,它也假设它得到了迭代器,并试图对其进行迭代器。因此,由于它是一个迭代器,因此需要一些时间来迭代和编写它。明白了吗?
作为Martijn答案的补充,最好的方法是首先避免使用
join
构建列表只需将生成器理解传递给
writelines
,在末尾添加新行:没有不必要的内存分配和循环(除了理解之外)file.writelines()
需要字符串的iterable。然后继续循环并为iterable中的每个字符串调用file.write()
。在Python中,该方法执行以下操作:您传入的是一个大字符串,字符串也是一个iterable字符串。迭代时,您将得到个字符,长度为1的字符串。所以实际上,您正在对
len(data)
进行单独的调用。这很慢,因为您一次只能构建一个字符的写缓冲区。不要将单个字符串传递给
file.writelines()
。改为传入列表、元组或其他iterable。可以通过在生成器表达式中添加换行符来发送单独的行,例如:
现在,如果您可以生成
clean_data()
a生成器,生成已清理的行,那么您可以从输入文件、通过数据清理生成器流式传输数据,并输出到输出文件,而无需使用比读写缓冲区所需更多的内存,而且无论需要多少状态来清理行:此外,我会考虑更新
clean_data()
以发出包含新行的行。相关问题 更多 >
编程相关推荐