Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中加快逐行打印到文件的速度?_Python_Python 3.x - Fatal编程技术网

如何在Python中加快逐行打印到文件的速度?

如何在Python中加快逐行打印到文件的速度?,python,python-3.x,Python,Python 3.x,假设我正在将两个数组中的数字打印到一个文件中: from numpy import random number_of_points = 10000 a = random.rand(number_of_points) b = random.rand(number_of_points) fh = open('file.txt', 'w') for i in range(number_of_points): for j in range(number_of_points): p

假设我正在将两个数组中的数字打印到一个文件中:

from numpy import random
number_of_points = 10000
a = random.rand(number_of_points)
b = random.rand(number_of_points)
fh = open('file.txt', 'w')
for i in range(number_of_points):
    for j in range(number_of_points):
        print('%f %f' % (a[i], b[j]), file=fh)

我觉得这会给系统打很多电话打印,而发送一个包含这些信息的电话会更快。这是正确的吗?如果是,我该怎么做?有没有更快的方法来实现这一点?

print
有很多你没有使用的东西,你使用的是C风格的循环索引,而不是直接迭代,这两种方法都增加了不必要的开销。通过限制Python级别的工作,将其推到C层,您可能可以稍微加快它的速度

例如,在这种情况下,可以将整个双嵌套循环结构替换为:

import itertools

# You could use '%f %f\n'.__mod__ as the map function if you like, I just
# find the modern format strings a little nicer
fh.writelines(itertools.starmap('{} {}\n'.format, itertools.product(a, b)))
它使用
product
直接生成嵌套循环和索引的结果,
starmap
+
str.format
创建行,
fh.writelines
耗尽由
starmap
创建的生成器,通过单个函数调用将其所有输出直接写入文件,而不是100000000次调用
print


除了创建生成器并将最终生成器传递给
fh.writelines
所需的固定(与迭代的项数无关)设置成本外,实际的迭代、格式化和I/O工作将完全在CPython引用解释器的C层上进行,因此它应该运行得相当快。

有多慢?测试后,您是否确定它对于您的目的来说太慢了?如果是这样,您确定罪魁祸首是重复的
print
调用吗?您是否尝试过
打印('\n'.join(['%f%f%](a[i],b[i])以获得范围内的i(点数)])
?在我的应用程序中,此段的速度需要提高。分析pins
打印
作为罪魁祸首。对于嵌套的for循环,我将如何执行上述操作?上面编辑为包含嵌套的
for
循环。@TigerhawkT3:该建议将在内存中创建一个100米的
str
项目
列表,以及一个
str
,所有项目的组合长度为所需的峰值RAM。这是所需的多GB内存,比许多系统拥有的内存都多。您不希望使用不逐段写入的解决方案来解决此问题。数据将写入本地缓冲区,并在缓冲区填满时刷新到系统缓存。您将得到一个较小的提升,内部缓冲区更大,如
fh=open('file.txt','w',2**24)
,它创建了一个16兆的缓冲区。最终,系统缓冲区填满,程序速度减慢到磁盘I/O速度。假设我在
tmpfs
上执行此I/O(仅供参考,我正在“粘合”两个封闭源程序,它们相互传输大量数据,即一个程序的修改输出是另一个程序的输入)。该缓冲区是否出现在RAM或其他设备缓存中?如果缓冲区出现在RAM中,似乎存在冗余,我应该一起放弃缓冲区。即使没有itertools(这可能不适合OP的真实代码,以及他的示例)。使用
file.write
是一个很好的技巧。打印速度可能会快一倍。@t请告诉我与打印()相比,
io.TextIOBase.write
io.IOBase.writelines
有什么性能优势?似乎
print()
io.TextIOBase.write都是逐行缓冲的,而
io.IOBase.writelines(行)
缓冲的是所有行?这是正确的吗?@bfletch我不知道为什么
打印速度较慢,但这不是行缓冲的问题。缓冲是在文件打开时决定的。终端默认为行缓冲,而文件和管道默认为块缓冲-您的打印没有行缓冲。在一次测试中,我将文件缓冲区大小增加到了16兆,尽管系统写入的数量下降了2000倍,但总体执行时间保持不变,当我更改为
write
时,执行时间下降了约40%。因此,问题在于打印速度慢,而不是系统缓冲。您的里程可能会有所不同@ShadowRanger使用此解决方案,我得到
索引器:元组索引超出范围。@bfletch:Oops,我的错误。对于
格式
调用,需要使用
itertools.starmap
,而不是普通的
map
。固定的。如果使用
'%f%f\n.\uuu mod\uuu
作为映射函数,则将使用普通的
映射。