参考基准
测试环境:
使用您的示例文件patterns.txt
,共50,000行,和contents.txt
,也共50,000行。
所有解决方案都加载了patterns.txt
中的所有行,但只检查contents.txt
的前1000行。
测试笔记本电脑配备了双核64位Intel(R)Celeron(R)CPU N3050 @ 2.16GHz,4 GB RAM,Debian 9 64位测试版,gnu sed 4.4
和gnu awk 4.1.4
。
在所有情况下,输出都发送到新文件中,以避免在屏幕上打印数据时出现缓慢的开销。
结果:
1. RavinderSingh13第一种awk解决方案
$ time awk 'FNR==NR{a[$1]=$2;next} {for(i in a){match($0,i);val=substr($0,RSTART,RLENGTH);if(val){sub(val,a[i])}};print}' patterns.txt <(head -n 1000 contents.txt) >newcontents.txt
real 19m54.408s
user 19m44.097s
sys 0m1.981s
2. EdMorton的第一个awk解决方案
$ time awk 'NR==FNR{map[$1]=$2;next}{for (old in map) {gsub(old,map[old])}print}' patterns.txt <(head -n1000 contents.txt) >newcontents.txt
real 20m3.420s
user 19m16.559s
sys 0m2.325s
3. Sed(我的sed)解决方案
$ time sed -f <(printf 's/%s/%s/g\n' $(<patterns.txt)) <(head -n 1000 contents.txt) >newcontents.txt
real 1m1.070s
user 0m59.562s
sys 0m1.443s
4. Cyrus sed解决方案
$ time sed -f <(sed -E 's|(.*) (.*)|s/\1/\2/|g' patterns.txt) <(head -n1000 contents.txt) >newcontents.txt
real 1m0.506s
user 0m59.871s
sys 0m1.209s
5. RavinderSingh13的第二个awk解决方案
$ time awk 'FNR==NR{a[$1]=$2;next}{for(i in a){match($0,i);val=substr($0,RSTART,RLENGTH);if(val){sub(val,a[i]);print;next}};}1' patterns.txt <(head -n 1000 contents.txt) >newcontents.txt
real 0m25.572s
user 0m25.204s
sys 0m0.040s
对于像1000行这样的少量输入数据,awk解决方案似乎很好。现在我们来测试一下9000行数据的性能比较。
6.RavinderSingh13的第二个awk解决方案,使用了9000行数据。
$ time awk 'FNR==NR{a[$1]=$2;next}{for(i in a){match($0,i);val=substr($0,RSTART,RLENGTH);if(val){sub(val,a[i]);print;next}};}1' patterns.txt <(head -9000 contents.txt) >newcontents.txt
real 22m25.222s
user 22m19.567s
sys 0m2.091s
7. 9000行的Sed解决方案
$ time sed -f <(printf 's/%s/%s/g\n' $(<patterns.txt)) <(head -9000 contents.txt) >newcontents.txt
real 9m7.443s
user 9m0.552s
sys 0m2.650s
8. 使用9000行并行Seds解决方案
$ cat sedpar.sh
s=$SECONDS
sed -f <(printf 's/%s/%s/g\n' $(<patterns.txt)) <(head -3000 contents.txt) >newcontents1.txt &
sed -f <(printf 's/%s/%s/g\n' $(<patterns.txt)) <(tail +3001 contents.txt |head -3000) >newcontents2.txt &
sed -f <(printf 's/%s/%s/g\n' $(<patterns.txt)) <(tail +6001 contents.txt |head -3000) >newcontents3.txt &
wait
cat newcontents1.txt newcontents2.txt newcontents3.txt >newcontents.txt && rm -f newcontents1.txt newcontents2.txt newcontents3.txt
echo "seconds elapsed: $(($SECONDS-$s))"
$ time ./sedpar.sh
seconds elapsed: 309
real 5m16.594s
user 9m43.331s
sys 0m4.232s
将任务分成更多的命令,比如三个并行的sed,似乎可以加快速度。
如果您想在自己的电脑上重复基准测试,可以通过OP的链接或我的github下载文件
contents.txt
和
patterns.txt
:
contents.txt
patterns.txt