gpt4 book ai didi

python - 并行文件写入是否高效?

转载 作者:太空狗 更新时间:2023-10-29 17:42:44 25 4
gpt4 key购买 nike

我想知道并行文件写入是否有效。实际上,硬盘一次只有一个可用的读头。因此 HDD 可以一次完成一项任务。但是下面的测试(在 python 中)与我的预期相矛盾:

要复制的文件大约为 1 Gb

脚本 1(//任务逐行读写同一个文件 10 次):

#!/usr/bin/env python
from multiprocessing import Pool
def read_and_write( copy_filename ):
with open( "/env/cns/bigtmp1/ERR000916_2.fastq", "r") as fori:
with open( "/env/cns/bigtmp1/{}.fastq".format( copy_filename) , "w" ) as fout:
for line in fori:
fout.write( line + "\n" )
return copy_filename

def main():
f_names = [ "test_jm_{}".format(i) for i in range( 0, 10 ) ]
pool = Pool(processes=4)
results = pool.map( read_and_write, f_names )

if __name__ == "__main__":
main()

脚本2(任务对同一个文件逐行读写10次):

#!/usr/bin/env python
def read_and_write( copy_filename ):
with open( "/env/cns/bigtmp1/ERR000916_2.fastq", "r") as fori:
with open( "/env/cns/bigtmp1/{}.fastq".format( copy_filename) , "w" ) as fout:
for line in fori:
fout.write( line + "\n" )
return copy_filename

def main():
f_names = [ "test_jm_{}".format(i) for i in range( 0, 10 ) ]
for n in f_names:
result = read_and_write( n )

if __name__ == "__main__":
main()

脚本 3(//复制同一个文件 10 次的任务):

#!/usr/bin/env python
from shutil import copyfile
from multiprocessing import Pool
def read_and_write( copy_filename ):
copyfile( "/env/cns/bigtmp1/ERR000916_2.fastq", "/env/cns/bigtmp1/{}.fastq".format( copy_filename) )
return copy_filename

def main():
f_names = [ "test_jm_{}".format(i) for i in range( 0, 10 ) ]
pool = Pool(processes=4)
results = pool.map( read_and_write, f_names )

if __name__ == "__main__":
main()

脚本 4(复制同一个文件 10 次的任务):

#!/usr/bin/env python
from shutil import copyfile
def read_and_write( copy_filename ):
copyfile( "/env/cns/bigtmp1/ERR000916_2.fastq", "/env/cns/bigtmp1/{}.fastq".format( copy_filename) )
return copy_filename

def main():
f_names = [ "test_jm_{}".format(i) for i in range( 0, 10 ) ]
for n in f_names:
result = read_and_write( n )

if __name__ == "__main__":
main()

结果:

$ # // task to read and write line by line 10 times a same file
$ time python read_write_1.py

real 1m46.484s
user 3m40.865s
sys 0m29.455s

$ rm test_jm*
$ # task to read and write line by line 10 times a same file
$ time python read_write_2.py

real 4m16.530s
user 3m41.303s
sys 0m24.032s

$ rm test_jm*
$ # // task to copy 10 times a same file
$ time python read_write_3.py

real 1m35.890s
user 0m10.615s
sys 0m36.361s


$ rm test_jm*
$ # task to copy 10 times a same file
$ time python read_write_4.py

real 1m40.660s
user 0m7.322s
sys 0m25.020s
$ rm test_jm*

这些基础结果似乎表明//io 读写效率更高。

谢谢你的光

最佳答案

I would like to know if parallel file writing is efficient.

简短回答:物理上同时从多个线程写入同一磁盘,永远不会比从一个线程写入该磁盘快(谈论正常硬盘在这里)。在某些情况下,它甚至会慢很多。

但是,一如既往,这取决于很多因素:

  • 操作系统磁盘缓存:写入通常由操作系统保存在缓存中,然后以 block 的形式写入磁盘。因此多个线程可以毫无问题地同时写入该缓存,并且这样做具有速度优势。特别是如果数据的处理/准备时间超过磁盘的写入速度。

  • 在某些情况下,即使从多个线程直接写入物理磁盘,操作系统也会对此进行优化,并且只将大块写入每个文件。

  • 然而,在最坏的情况下,每次都可能将较小的 block 写入磁盘,从而导致每次文件切换时都需要进行硬盘寻道(普通硬盘需要 ± 10 毫秒!)(执行相同操作在 SSD 上不会那么糟糕,因为有更多的直接访问并且不需要查找)。

因此,一般来说,当同时从多个线程写入磁盘时,在内存中准备(一些)数据可能是个好主意,然后使用某种锁将最终数据以更大的 block 写入磁盘,或者也许来自一个专用的 writer-thread。如果文件在写入时不断增长(即没有预先设置文件大小),将数据写入更大的 block 也可以防止磁盘碎片(至少尽可能多)。

在某些系统上可能根本没有区别,但在其他系统上可能会有很大的不同,并且会变得很慢(甚至在具有不同硬盘的同一系统上)。

要很好地测试使用单线程与多线程的写入速度差异,总文件大小必须大于可用内存 - 或者至少应在测量结束时间之前将所有缓冲区刷新到磁盘.仅测量将数据写入操作系统磁盘缓存所需的时间在这里没有多大意义。

理想情况下,将所有数据写入磁盘的总时间应该等于物理硬盘的写入速度。如果使用一个线程写入磁盘比磁盘写入速度慢(这意味着处理数据比写入数据花费的时间更长),显然使用更多线程会加快速度。如果多线程写入变得比磁盘写入速度慢,则在不同文件(或同一大文件内的不同 block )之间切换会导致磁盘寻道时间丢失。

为了了解执行大量磁盘寻道时的时间损失,让我们看一些数字:

比如说,我们有一个写入速度为 50MB/s 的硬盘:

  • 写入一个 50MB 的连续 block 需要 1 秒(在理想情况下)。

  • 在 1MB 的 block 中执行相同的操作,使用 file-switch 并在两者之间产生磁盘寻道将得到:20ms 写入 1MB + 10ms 寻道时间。写入 50MB 需要 1.5 秒。这增加了 50% 的时间,只是为了在两者之间进行快速查找(同样适用于从磁盘读取 - 考虑到更快的读取速度,差异甚至会更大)。 p>

实际上它会介于两者之间,具体取决于系统。

虽然我们希望操作系统能够妥善处理所有这些(或者通过使用 IOCP 等方式),但情况并非总是如此。

关于python - 并行文件写入是否高效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34667551/

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