- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想知道并行文件写入是否有效。实际上,硬盘一次只有一个可用的读头。因此 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/
我有一个 if 语句,如下所示 if (not(fullpath.lower().endswith(".pdf")) or not (fullpath.lower().endswith(tup
然而,在 PHP 中,可以: only appears if $foo is true. only appears if $foo is false. 在 Javascript 中,能否在一个脚
XML有很多好处。它既是机器可读的,也是人类可读的,它具有标准化的格式,并且用途广泛。 它也有一些缺点。它是冗长的,不是传输大量数据的非常有效的方法。 XML最有用的方面之一是模式语言。使用模式,您可
由于长期使用 SQL2000,我并没有真正深入了解公用表表达式。 我给出的答案here (#4025380)和 here (#4018793)违背了潮流,因为他们没有使用 CTE。 我很欣赏它们对于递
我有一个应用程序: void deleteObj(id){ MyObj obj = getObjById(id); if (obj == null) { throw n
我的代码如下。可能我以类似的方式多次使用它,即简单地说,我正在以这种方式管理 session 和事务: List users= null; try{ sess
在开发J2EE Web应用程序时,我通常会按以下方式组织我的包结构 com.jameselsey.. 控制器-控制器/操作转到此处 服务-事务服务类,由控制器调用 域-应用程序使用的我的域类/对象 D
这更多是出于好奇而不是任何重要问题,但我只是想知道 memmove 中的以下片段文档: Copying takes place as if an intermediate buffer were us
路径压缩涉及将根指定为路径上每个节点的新父节点——这可能会降低根的等级,并可能降低路径上所有节点的等级。有办法解决这个问题吗?有必要处理这个吗?或者,也许可以将等级视为树高的上限而不是确切的高度? 谢
我有两个类,A 和 B。A 是 B 的父类,我有一个函数接收指向 A 类型类的指针,检查它是否也是 B 类型,如果是将调用另一个函数,该函数接受一个指向类型 B 的类的指针。当函数调用另一个函数时,我
有没有办法让 valgrind 使用多个处理器? 我正在使用 valgrind 的 callgrind 进行一些瓶颈分析,并注意到我的应用程序中的资源使用行为与在 valgrind/callgrind
假设我们要使用 ReaderT [(a,b)]超过 Maybe monad,然后我们想在列表中进行查找。 现在,一个简单且不常见的方法是: 第一种可能性 find a = ReaderT (looku
我的代码似乎有问题。我需要说的是: if ( $('html').attr('lang').val() == 'fr-FR' ) { // do this } else { // do
根据this文章(2018 年 4 月)AKS 在可用性集中运行时能够跨故障域智能放置 Pod,但尚不考虑更新域。很快就会使用更新域将 Pod 放入 AKS 中吗? 最佳答案 当您设置集群时,它已经自
course | section | type comart2 : bsit201 : lec comart2 :
我正在开发自己的 SDK,而这又依赖于某些第 3 方 SDK。例如 - OkHttp。 我应该将 OkHttp 添加到我的 build.gradle 中,还是让我的 SDK 用户包含它?在这种情况下,
随着 Rust 越来越充实,我对它的兴趣开始激起。我喜欢它支持代数数据类型,尤其是那些匹配的事实,但是对其他功能习语有什么想法吗? 例如标准库中是否有标准过滤器/映射/归约函数的集合,更重要的是,您能
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 9 年前。 Improve
我一直在研究 PHP 中的对象。我见过的所有示例甚至在它们自己的对象上都使用了对象构造函数。 PHP 会强制您这样做吗?如果是,为什么? 例如: firstname = $firstname;
...比关联数组? 关联数组会占用更多内存吗? $arr = array(1, 1, 1); $arr[10] = 1; $arr[] = 1; // <- index is 11; does the
我是一名优秀的程序员,十分优秀!