我目前正在使用cp -r
.
有没有办法更快地做到这一点?首先压缩文件会更好,还是使用rsync
?
答案1
最近我对有时缓慢的速度感到困惑cp
。具体来说,为什么df = pandas.read_hdf('file1', 'df')
(1.2GB 文件需要 700 毫秒)后面跟着df.to_hdf('file2')
(530 毫秒)会比cp file1 file2
(8 秒)快这么多?
深入研究这一点:
cat file1 > file2
并没有好多少(8.1s)。dd bs=1500000000 if=file1 of=file2
两者都没有(8.3 秒)。rsync file1 file2
更糟糕(11.4s),因为 file2 已经存在,所以它尝试执行滚动校验和和块更新魔法。
哦,等一下!file2
如果存在的话,先 取消链接(删除)怎么样?
现在我们正在谈论:
rm -f file2
:0.2s(添加到下面的任何数字中)。cp file1 file2
:1.0秒。cat file1 > file2
:1.0秒。dd bs=1500000000 if=file1 of=file2
:1.2秒。rsync file1 file2
:4秒。
所以你有它。确保目标文件不存在(或截断它们,这可能是pandas.to_hdf()
存在的)。
编辑:这并没有在执行任何命令之前清空缓存,但正如注释中所述,这样做只会为上述所有数字持续增加约 3.8 秒。
另外值得注意的是:这已在各种 Linux 版本(Centos w. 2.6.18-408.el5 内核和 Ubuntu w. 3.13.0-77-generic 内核)以及 ext4 和 ext3 上进行了尝试。有趣的是,在装有 Darwin 10.12.6 的 MacBook 上,没有区别,并且两个版本(无论目标位置是否存在现有文件)都很快。
答案2
一样的分割(和文件系统)您可以用来-l
实现硬链接而不是副本。硬链接创建比复制内容要快得多(但是,当然,它不能跨不同的磁盘分区工作)。
举一个小例子:
$ time cp -r mydir mydira
real 0m1.999s
user 0m0.000s
sys 0m0.490s
$ time cp -rl mydir mydirb
real 0m0.072s
user 0m0.000s
sys 0m0.007s
这是 28 倍的改进。但该测试仅使用了约 300 个(相当小的)文件。几个较大的文件应该执行得更快,许多较小的文件应该执行得更慢。
答案3
在本地磁盘上复制一个文件,99%的时间都花在了磁盘的读写上。如果你尝试压缩数据,那么你会增加 CPU 负载,但不会减少读/写数据......它实际上会减速你的副本。
如果您已经拥有数据的副本并使其“最新”,rsync 将会有所帮助。
但是,如果您想创建一棵树的全新副本,那么您实际上无法比您的命令做得更好cp
。
答案4
要复制大量目录,您能cp
实际上比并行化副本和使用复制加速做得更好。
并行化副本将确保您的驱动器饱和。现代 SSD(某种程度上 HDD)在收到许多 I/O 请求时性能会更好,因为这些请求可以重新排序/批处理/缓存以获得最佳性能。除非要复制的文件很大并且操作系统执行预取,否则单线程复制不可能使 SSD 饱和。另一方面,多线程复制可确保许多文件读取和写入同时发生。
复制加速仅在某些文件系统上可用,但胜过其他所有系统,因为它实际上并不执行复制。相反,它将原始文件标记为已“COWed”,并且当稍后写入任一文件时,将执行实际的副本。您可能会说这只是推迟工作,但“稍后”部分为我们提供了额外的信息。例如,如果仅更改了某些磁盘块,则文件系统可以仅复制/创建那些新块并保留指向原始文件中的其他块的指针。或者文件系统可能不支持块级复制粒度,但您的更改完全覆盖了某些磁盘块......这些不再需要复制。我的观点是,复制加速不仅仅是“推迟工作”,它让我们看到未来。
io_uring 尚不支持复制加速,但一旦支持,使用它将通过以最小的开销并行执行复制所需的各种操作来进一步提高效率。
我创建了一个多线程替代品,cp
其唯一目的是成为复制文件的最快方法。目前,在复制没有嵌套的单个目录时,它不会脱颖而出,但我预计一旦 Linux 支持 io_uring 中的复制加速,这种情况就会改变。
工具:https://github.com/SUPERCILEX/fuc/tree/master/cpz
基准:https://github.com/SUPERCILEX/fuc/tree/master/comparisons#copy