我遇到了一个奇怪的问题。我有一个大文件(可能超过 1,000,000,000 行),其中仅包含一个代表文件大小的列。看起来像
55568
9700
7243
9692
63
5508
1679
14072
.....
我想计算每个值的出现次数。我使用两个不同的脚本
注意::下面使用的文件被剪切,仅包含 10,000 行!!!
bob@bob-ruby:~$ cat 1.sh
#!/bin/bash
while read size ; do
set -- $size
((count[$1]++))
done < file-size.txt
bob@bob-ruby:~$
bob@bob-ruby:~$ cat 2.sh
#!/bin/bash
awk '{count[$1]++}' file-size.txt
bob@bob-ruby:~$
我发现 1.sh (纯 shell 脚本)比 2.sh (awk-script)慢得多
bob@bob-ruby:~$ time bash 2.sh
real 0m0.045s
user 0m0.012s
sys 0m0.032s
bob@bob-ruby:~$ time bash 1.sh
real 0m0.618s
user 0m0.508s
sys 0m0.112s
bob@bob-ruby:~$
通过'strace'命令,我发现1.sh产生了很多syscall,而'2.sh'却少得多,这是为什么呢?
那是“awk”在里面做一些“魔术”吗?
bob@bob-ruby:~$ strace -c bash 1.sh
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
38.62 0.042011 1 30320 rt_sigprocmask
29.97 0.032597 2 20212 _llseek
15.33 0.016674 2 10115 read
12.57 0.013675 1 10106 10106 ioctl
(cut)
bob@bob-ruby:~$ strace -c bash 2.sh
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
95.52 0.008000 4000 2 1 waitpid
3.20 0.000268 21 13 5 access
1.28 0.000107 5 21 fstat64
0.00 0.000000 0 9 read