昨日の記事「シェルで回答してみる〜」の補足
毛利です。
シェルで回答してみる「シェル操作課題 (cut, sort, uniq などで集計を行う) 設問編」 - pmekyky385の日記
「高速なコマンドを使う」って自分で書いてて全く検証しておらず、気になったので少しだけ。
(見直すと「シェルで回答」ってなんか違和感あるな。UNIXコマンドで回答、かな?(この場合「UNIX」ってつけていいのか分からない))
アクセスログとかだとかなり大きめのファイルになるはずなので。
※後で気づきましたが、Time Machineを停止するとか、そこまで気を使ってません。でも、少なくとも問2の検証では走ってないはず(問8は時間がかかって放置したので走ってるかも。。)
timeで処理時間を検証「問2 このファイルからサーバー名とアクセス先だけ表示しろ」
$ cut -d, -f1,4 data.csv $ awk -F, '{printf("%s,%s\n",$1,$4)}' data.csv $ sed -e 's/^\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\)$/\1,\4/' data.csv $ perl -F, -a -nle 'print join(",",$F[0],$F[3])' data.csv
単純にtimeを使う。
まず、数行しかないdata.csv。結果は表示しない(> /dev/null)
$ wc -l data.csv 9 data.csv $ time cut -d, -f1,4 data.csv > /dev/null real 0m0.002s user 0m0.001s sys 0m0.001s $ time awk -F, '{printf("%s,%s\n",$1,$4)}' data.csv > /dev/null real 0m0.003s user 0m0.001s sys 0m0.002s $ time sed -e 's/^\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\)$/\1,\4/' data.csv > /dev/null real 0m0.003s user 0m0.001s sys 0m0.002s $ time perl -F, -a -nle 'print join(",",$F[0],$F[3])' data.csv > /dev/null real 0m0.168s user 0m0.004s sys 0m0.025s
data.csvを1GBぐらいのファイルに膨らませて検証
300byteぐらいだったので、1GB「ぐらい」になるまで繰り返し。
ls -l data.csv -rw-r--r-- 1 xxxxxxxxxxx wheel 302 12 5 11:46 data.csv $ time for i in $(seq 1 3333333) ; do cat data.csv >> bigdata.csv ; done ^C # 終わらない…。一旦停止 $ ls -l bigdata.csv -rw-r--r-- 1 xxxxxxxxxxx wheel 108440952 12 7 00:54 bigdata.csv $ cp bigdata.csv bigdata.csv.100mb $ cat /dev/null > bigdata.csv $ time for i in $(seq 1 10) ; do cat bigdata.csv.100mb >> bigdata.csv ; done real 0m15.735s user 0m0.074s sys 0m2.480s $ du -sh bigdata.csv 1.0G bigdata.csv
まあ、ざっくり1GBということ。
検証結果
$ time cut -d, -f1,4 bigdata.csv > /dev/null real 0m45.586s user 0m44.980s sys 0m0.572s $ time awk -F, '{printf("%s,%s\n",$1,$4)}' bigdata.csv > /dev/null real 0m49.794s user 0m49.062s sys 0m0.697s $ time sed -e 's/^\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\)$/\1,\4/' bigdata.csv > /dev/null real 1m55.168s user 1m53.997s sys 0m0.917s $ time perl -F, -a -nle 'print join(",",$F[0],$F[3])' bigdata.csv > /dev/null real 2m4.089s user 2m2.769s sys 0m1.122s
こういう単純なものはシンプルが早いか。
timeで処理時間を検証「問8 このログのアクセス先ごとにアクセス数を数え上位1つを表示しろ」
回答したものと、人様のperlを使ったワンライナー回答を比べてみる。
$ time cut -d, -f4 bigdata.csv | sort | uniq -c | sort -k1n | tail -1 14363040 /profile.php real 14m13.132s user 14m42.638s sys 0m4.538s $ time perl -aF, -nle '$m{$F[3]}++;eof&&print join" ",@{(sort{$b->[0]<=>$a->[0]}map{[$m{$_},$_]}keys%m)[0]}' bigdata.csv 14363040 /profile.php real 1m57.723s user 1m56.765s sys 0m0.867s
perlはやっ!!
いじょ。