我正在尝试进行基准测试以比较两种不同的文件处理方式。我有少量输入数据,但为了获得良好的比较,我需要多次重复测试。
我不只是重复测试,而是想多次复制输入数据(例如 1000 次),这样一个 3 行的文件就变成了 3000 行,这样我就可以运行一个更令人满意的测试。
我通过文件名传递输入数据:
mycommand input-data.txt
我正在尝试进行基准测试以比较两种不同的文件处理方式。我有少量输入数据,但为了获得良好的比较,我需要多次重复测试。
我不只是重复测试,而是想多次复制输入数据(例如 1000 次),这样一个 3 行的文件就变成了 3000 行,这样我就可以运行一个更令人满意的测试。
我通过文件名传递输入数据:
mycommand input-data.txt
你不需要
input-duplicated.txt
。尝试:
解释
0777
:-0
sets 设置输入记录分隔符(perl 特殊变量$/
,默认为换行符)。将其设置为大于的值0400
将导致 Perl 将整个输入文件拖入内存。pe
:-p
意思是“在应用给它的脚本后打印每个输入行-e
”。$_=$_ x 1000
:$_
是当前输入行。因为我们一次读取整个文件,所以-0700
这意味着整个文件。这x 1000
将导致打印整个文件的 1000 份副本。我原本以为我必须生成一个辅助文件,但我可以在 Bash 中循环原始文件并使用一些重定向使其显示为文件。
可能有十几种不同的循环方式,但这里有四种:
第三种方法是根据下面 maru 的评论即兴创作的,并为 cat 构建了一个输入文件名的大列表。
xargs
将把它分成系统允许的尽可能多的参数。它比n只单独的猫快得多。这种
awk
方式(受terdon 的回答启发)可能是最优化的,但它一次复制每一行。这可能适合也可能不适合特定的应用程序,但它闪电般快速且高效。但这是即时生成的。Bash 输出可能比某些东西可以读取的要慢得多,因此您应该生成一个新文件进行测试。值得庆幸的是,这只是一个非常简单的扩展:
我只会使用文本编辑器。
如果您绝对需要通过命令行执行此操作(这需要您
vim
安装,因为vi
没有:normal
命令),您可以使用:在这里,
-es
(或-e -s
)让 vim 静默运行,所以它不应该接管你的终端窗口,并-u NONE
阻止它查看你的 vimrc,这应该使它运行得比其他方式快一点(如果你使用,可能会快得多很多 vim 插件)。这是一个
awk
解决方案:它基本上和@Gnuc 的 Perl 一样快(我都运行了 1000 次并得到了平均时间):
这是一个简单的单行代码,不涉及脚本:
解释
`yes input-data.txt | head -1000 | paste -s`
input-data.txt
生成由空格分隔 1000 次的文本cat
作为文件列表传递给在处理完全不同的脚本时,我了解到,对于 2900 万行文本,按字节使用
seek()
和操作数据通常比逐行更快。下面的脚本中应用了相同的想法:我们打开文件,而不是循环打开和关闭文件(这可能会增加开销,即使不重要),我们保持文件打开并返回到开头。脚本本身的使用非常简单:
对于 3 行文本文件和 1000 次迭代,一切正常,大约 0.1 秒:
脚本本身不是最优雅的,可能可以缩短,但可以完成工作。当然,我在这里和那里添加了一些额外的位,比如
error_out()
功能,这不是必需的——这只是一个小的用户友好的触摸。我们可以解决这个问题,不需要额外的文件,也不需要特殊的程序,纯 Bash(好吧,cat 是一个标准命令)。
基于 bash 中 printf 的一个特性,我们可以生成一个重复的字符串):
然后,我们可以发送这样的 1000 个文件名列表(重复)并调用 cat:
最后,我们可以将输出提供给要执行的命令:
或者,如果命令需要接收标准输入中的输入:
是的,双 < 是必需的。
我将使用 Unix for 循环生成一个新文件: