readは、指定されたファイルディスクリプタから、バイナリデータをバッファに読み込むUNIXシステムコール・・・。
freadも最終的にはこのreadを呼ぶが、なぜfreadとreadを使い分けるのか・・・。
2パターンのバイナリデータをreadとfreadでそれぞれ読み込んでみて検証する・・・。
まずパターン1・・・。
read_1.cにて、
こちらで用意するバッファbufのサイズは4・・・。
一方、
高水準入出力関数がもともと利用しているバッファのサイズは、stdio.hの中にBUFSIZとして定義されているのでそれを出力・・・。
$ ./read_1 BUFSIZ = 8192
ここでは8192となっている・・・。
そして、test_1.txtというファイルを用意する・・・。
これは"ABCD"という文字列を2048回並べた8192バイトのファイルである・・・。
BUFSIZと同じ・・・。
test_1.txtをopenで開いて、
4バイトのbufに2048回読み込む・・・。
この処理にかかった実時間をtimeコマンドで計測する・・・。
$ time ./read_1 BUFSIZ = 8192 read start read end real 0m0.030s user 0m0.002s sys 0m0.007s $
0.030秒かかっている・・・。
さて、つづいてはfreadで同じファイルを同じ方法で読み込んでみる・・・。
fread_1.cで、
同じように4バイトのバッファに2048回読み込む・・・。
これをtimeで実行すると、
$ time ./fread_1 BUFSIZ = 8192 fread start fread end real 0m0.010s user 0m0.000s sys 0m0.004s $
0.010秒で済んでいる・・・。
場合によってはあまり差がない場合もあるが、たいていはfreadのほうが速い・・・。
BUFSIZ以下のデータを繰り返し読み込む場合、
バッファリング機能のあるfreadは、BUFSIZ分まで実際にはreadを呼ばない・・・。
BUFSIZに到達したら読み込むので、実際にreadが呼ばれて、処理速度の遅い入出力装置にアクセスするのは1回だけである・・・。
一方、たとえ4バイトでもreadを1回呼んだだけでそれなりの時間はかかる・・・。
2048回呼べば、1回readを呼ぶだけのfreadより遅くなるのは合点がいく・・・。
ただ、実際にはこのようにあまり差が出ない場合が多い・・・。
まとめると、BUFSIZ以下のデータを繰り返し読み込む場合はfreadのほうが速い・・・。
次はパターン2・・・。
BUFSIZを超えるデータの読み込みはどうだろうか・・・。
read_2.cで、
バッファbufのサイズを819200、つまりBUFSIZの100倍用意する・・・。
そして、test_1.txtの100倍のサイズである、test_2.txtを用意する・・・。
そのtest_2.txtをopenで開いて、
readで、1回で819200バイト全部読み込む・・・。
$ time ./read_2 BUFSIZ = 8192 read start read end real 0m0.009s user 0m0.000s sys 0m0.005s $ time ./read_2
readでは0.009秒かかる・・・。
では、freadの場合はどうだろうか・・・。
同じようにサイズが819200バイトのバッファを自前で用意し、
fopenでtest_2.txtを開いて、
819200バイトをfopenで1回で読み込む・・・。
$ time ./fread_2 BUFSIZ = 8192 fread start fread end real 0m0.016s user 0m0.002s sys 0m0.003s $
0.016秒かかっている・・・。
freadは内部ではreadで8192バイトずつ読み込んでいるので、それ以上となると、1回内部バッファをフラッシュして再びreadを呼んで読み込まなければならない・・・。
結果的にreadを100回呼んでいるので時間がかかる・・・。
まとめると、BUFSIZ以上のデータを1回で一気に読み込む場合はreadのほうが速い・・・。
Sample/read_1.c at master · bg1bgst333/Sample · GitHub
Sample/fread_1.c at master · bg1bgst333/Sample · GitHub
Sample/read_2.c at master · bg1bgst333/Sample · GitHub
Sample/fread_2.c at master · bg1bgst333/Sample · GitHub