Closed. This question needs to be more
focused。它当前不接受答案。
想要改善这个问题吗?更新问题,使它仅关注
editing this post的一个问题。
已关闭6年。
Improve this question
已经讨论了这个问题
here on Meta,而我的
answer提供了指向测试系统的链接来回答这个问题。
由于性能原因,经常会出现关于是否使用gawk或mawk或C或其他某种语言的问题,因此让我们为平凡而又典型的awk程序创建一个规范的问题/答案。
这样的结果将是一个答案,它提供了对在简单输入文件上执行正则表达式匹配和字段拆分的基本文本处理任务的不同工具的性能的比较。如果用于该任务的工具X的速度是其他所有工具的两倍,那么这是有用的信息。如果所有工具花费的时间都差不多,那也是有用的信息。
这种方法的工作方式是,在接下来的几天中,许多人将提供“答案”(即要测试的程序),然后一个人(志愿者?)将在一个平台上测试所有这些程序(或者少数人将进行测试)。他们平台上的一些子集,以便我们进行比较),然后将所有结果收集到一个答案中。
给定此脚本创建的1000万行输入文件:
$ awk 'BEGIN{for (i=1;i<=10000000;i++) print (i%5?"miss":"hit"),i," third\t \tfourth"}' > file
$ wc -l file
10000000 file
$ head -10 file
miss 1 third fourth
miss 2 third fourth
miss 3 third fourth
miss 4 third fourth
hit 5 third fourth
miss 6 third fourth
miss 7 third fourth
miss 8 third fourth
miss 9 third fourth
hit 10 third fourth
并给出了这个awk脚本,该脚本会打印以“hit”开头并后面加上偶数的每行的第4个,第1个,然后第3个字段:
$ cat tst.awk
/hit [[:digit:]]*0 / { print $4, $1, $3 }
这是预期输出的前5行:
$ awk -f tst.awk file | head -5
fourth hit third
fourth hit third
fourth hit third
fourth hit third
fourth hit third
这是通过管道传输到第二个awk脚本以验证上面的主脚本实际上确实按预期运行时的结果:
$ awk -f tst.awk file |
awk '!seen[$0]++{unq++;r=$0} END{print ((unq==1) && (seen[r]==1000000) && (r=="fourth hit third")) ? "PASS" : "FAIL"}'
PASS
以下是在cygwin64上以bash 4.3.33运行的 gawk 4.1.1的
第3次执行的计时结果:
$ time awk -f tst.awk file > /dev/null
real 0m4.711s
user 0m4.555s
sys 0m0.108s
请注意,以上是删除缓存差异的第三次执行。
任何人都可以提供等效的C,perl,python,以及与此相关的任何代码:
$ cat tst.awk
/hit [[:digit:]]*0 / { print $4, $1, $3 }
例如,在一行上找到那个REGEXP(我们不是在寻找其他需要正则表达式的解决方案),在每个连续的空白序列处分割行,并打印第4个,第1个,第3个字段,并用一个空白字符?
如果是这样,我们可以在一个平台上测试它们,以查看/记录性能差异。
到目前为止,该代码做出了贡献:
AWK(可以针对gawk等进行测试,但是mawk,nawk以及其他可能需要[0-9]而不是[:digit:])
awk '/hit [[:digit:]]*0 / { print $4, $1, $3 }' file
的PHP
php -R 'if(preg_match("/hit \d*0 /", $argn)){$f=preg_split("/\s+/", $argn); echo $f[3]." ".$f[0]." ".$f[2];}' < file
shell
egrep 'hit [[:digit:]]*0 ' file | awk '{print $4, $1, $3}'
grep --mmap -E "^hit [[:digit:]]*0 " file | awk '{print $4, $1, $3 }'
ruby
$ cat tst.rb
File.open("file").readlines.each do |line|
line.gsub(/(hit)\s[0-9]*0\s+(.*?)\s+(.*)/) { puts "#{$3} #{$1} #{$2}" }
end
$ ruby tst.rb
佩尔
$ cat tst.pl
#!/usr/bin/perl -nl
# A solution much like the Ruby one but with atomic grouping
print "$4 $1 $3" if /^(hit)(?>\s+)(\d*0)(?>\s+)((?>[^\s]+))(?>\s+)(?>([^\s]+))$/
$ perl tst.pl file
Python
none yet
C
none yet
在awk之前应用egrep可以大大提高速度:
paul@home ~ % wc -l file
10000000 file
paul@home ~ % for i in {1..5}; do time egrep 'hit [[:digit:]]*0 ' file | awk '{print $4, $1, $3}' | wc -l ; done
1000000
egrep --color=auto 'hit [[:digit:]]*0 ' file 0.63s user 0.02s system 85% cpu 0.759 total
awk '{print $4, $1, $3}' 0.70s user 0.01s system 93% cpu 0.760 total
wc -l 0.00s user 0.02s system 2% cpu 0.760 total
1000000
egrep --color=auto 'hit [[:digit:]]*0 ' file 0.65s user 0.01s system 85% cpu 0.770 total
awk '{print $4, $1, $3}' 0.71s user 0.01s system 93% cpu 0.771 total
wc -l 0.00s user 0.02s system 2% cpu 0.771 total
1000000
egrep --color=auto 'hit [[:digit:]]*0 ' file 0.64s user 0.02s system 82% cpu 0.806 total
awk '{print $4, $1, $3}' 0.73s user 0.01s system 91% cpu 0.807 total
wc -l 0.02s user 0.00s system 2% cpu 0.807 total
1000000
egrep --color=auto 'hit [[:digit:]]*0 ' file 0.63s user 0.02s system 86% cpu 0.745 total
awk '{print $4, $1, $3}' 0.69s user 0.01s system 92% cpu 0.746 total
wc -l 0.00s user 0.02s system 2% cpu 0.746 total
1000000
egrep --color=auto 'hit [[:digit:]]*0 ' file 0.62s user 0.02s system 88% cpu 0.727 total
awk '{print $4, $1, $3}' 0.67s user 0.01s system 93% cpu 0.728 total
wc -l 0.00s user 0.02s system 2% cpu 0.728 total
相对:
paul@home ~ % for i in {1..5}; do time gawk '/hit [[:digit:]]*0 / { print $4, $1, $3 }' file > /dev/null; done
gawk '/hit [[:digit:]]*0 / { print $4, $1, $3 }' file > /dev/null 2.46s user 0.04s system 97% cpu 2.548 total
gawk '/hit [[:digit:]]*0 / { print $4, $1, $3 }' file > /dev/null 2.43s user 0.03s system 98% cpu 2.508 total
gawk '/hit [[:digit:]]*0 / { print $4, $1, $3 }' file > /dev/null 2.40s user 0.04s system 98% cpu 2.489 total
gawk '/hit [[:digit:]]*0 / { print $4, $1, $3 }' file > /dev/null 2.38s user 0.04s system 98% cpu 2.463 total
gawk '/hit [[:digit:]]*0 / { print $4, $1, $3 }' file > /dev/null 2.39s user 0.03s system 98% cpu 2.465 total
“nawk”更慢!
paul@home ~ % for i in {1..5}; do time nawk '/hit [[:digit:]]*0 / { print $4, $1, $3 }' file > /dev/null; done
nawk '/hit [[:digit:]]*0 / { print $4, $1, $3 }' file > /dev/null 6.05s user 0.06s system 92% cpu 6.606 total
nawk '/hit [[:digit:]]*0 / { print $4, $1, $3 }' file > /dev/null 6.11s user 0.05s system 96% cpu 6.401 total
nawk '/hit [[:digit:]]*0 / { print $4, $1, $3 }' file > /dev/null 5.78s user 0.04s system 97% cpu 5.975 total
nawk '/hit [[:digit:]]*0 / { print $4, $1, $3 }' file > /dev/null 5.71s user 0.04s system 98% cpu 5.857 total
nawk '/hit [[:digit:]]*0 / { print $4, $1, $3 }' file > /dev/null 6.34s user 0.05s system 93% cpu 6.855 total
我是一名优秀的程序员,十分优秀!