私は奇妙な問題に遭遇しました。file のサイズを表す単一の列のみを含む大きなファイル (おそらく 1,000,000,000 行以上) があります。のように見えます
55568
9700
7243
9692
63
5508
1679
14072
.....
そして、各値の出現回数を数えたいと思います。私は2つの異なるスクリプトを使用しています
注:: 以下で使用されるファイルは切り取られており、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 (純粋なシェル スクリプト) は 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