Bash 快速复制一个文件数千次

Bash 快速复制一个文件数千次,bash,performance,Bash,Performance,为了进行性能测试,我需要为一个文件制作数千份副本。在for循环中,使用bash脚本有没有比cp更快的方法?我知道存在用于创建数千个文件(rsync等)的一个副本的工具,但是否有一种工具可以利用源文件始终相同的事实来加快过程?您可以尝试tee。比如说, cat source.txt | tee copy1.txt copy2.txt copy3.txt > copy4.txt 它可能并不比运行多个cp拷贝快多少,但进程启动开销略小一些。(在这里,运行tee一次,而不是cp4次。)我认为所有

为了进行性能测试,我需要为一个文件制作数千份副本。在
for
循环中,使用bash脚本有没有比
cp
更快的方法?我知道存在用于创建数千个文件(rsync等)的一个副本的工具,但是否有一种工具可以利用源文件始终相同的事实来加快过程?

您可以尝试
tee
。比如说,

cat source.txt | tee copy1.txt copy2.txt copy3.txt > copy4.txt

它可能并不比运行多个
cp
拷贝快多少,但进程启动开销略小一些。(在这里,运行
tee
一次,而不是
cp
4次。)

我认为所有基于标准coreutils(cp、tee等)的方法或多或少都具有相同的性能。他们也有几十种你并不真正需要的不同选择,而且每一种都使用系统资源

如果您需要非常快速的东西,您可以自己编写
pcopy
。它不是很复杂,您可以使用copy.c(由cp和其他std coreutils程序使用)作为起点

我将采用以下方法:

  • 读取源文件一次并将其保存在内存中(假设可以)
  • 启动可配置数量的线程
  • 每个线程将源文件的相同副本写入磁盘(使用对齐块直接同步O_或异步IO)

  • 我认为以这种方式编码的pcopy比std coreutils快得多。

    基于@chepner的想法

    制作10000份副本需要6.3秒(每次8次):

    parallel -N 8 'cat source.txt | tee copy{1}.txt copy{2}.txt copy{3}.txt copy{4}.txt copy{5}.txt copy{6}.txt copy{7}.txt copy{8}.txt ' ::: {1..10000}
    
    这需要19秒(一次一个):

    这需要5秒(每次10秒):


    请注意,我在SSD上运行,旋转磁盘的结果可能更糟。

    将文件a复制到b1。。b1000

    echo b{1..1000}  | xargs -n 1 cp a
    

    查找GNU ParallelParallel的效率并不比
    for
    循环更高,只是语法更简洁。我认为写入磁盘会降低速度。@TomFenech很好,如果你连续多次访问一个文件,它最终会在某种程度上被缓存,我不会感到惊讶。然而,当你把它写到数千个不同的目的地时,这就是你要付出的代价。我想你也可以使用
    copy{0001..1000}.txt
    或其他一些东西来简化命名。
    数千个副本
    使用这个会很长时间。可能
    cat source.txt | tee copy{1..1000).txt
    根据每个副本文件名的长度,您可能仍然需要将其分为几轮,因为具有数千个参数的命令行可能太长(这实际上是
    parallel
    可以帮助的)。现代系统上的命令行限制是巨大的。
    xargs--show limits
    echo
    ,作为一个内置的shell,不受限制。很高兴知道,
    xargs
    提供了一种查看本地系统上的限制的方法。
    parallel
    没有一种方法可以用尽可能多的参数运行命令,而不是如果必须硬编码固定数量的参数?@chepner是的,但我正在努力解决如何将它们全部提取出来,并分别用
    copy
    作为前缀,用
    .txt
    :-)作为后缀,也许@OleTange将不得不再次帮助我!
    time parallel -N 10 'cat source.txt | tee copy{1}.txt copy{2}.txt copy{3}.txt copy{4}.txt copy{5}.txt copy{6}.txt copy{7}.txt copy{8}.txt copy{9}.txt copy{10}.txt' ::: {1..10000}
    
    echo b{1..1000}  | xargs -n 1 cp a