|
getchar()マクロってライブラリ側でbufferしてくれてるんじゃなかったの?というかライブラリのバッファが小さい?
|
[88]Re:getchar() へるみ . 2007 11/3(Sat) 1:37
|
|
されると思います.ただ今回のものはループ内の処理が少ないのでgetchar()の関数呼び出しが目立ってしまったという気がします.今どきはマルチスレッドからの呼び出しも考慮してるのかな.
|
|
|
[89]Re:getchar() dsk . 2007 11/6(Tue) 16:12
|
getchar()は今は関数なんですね!!昔はマクロじゃなかったっけ?stdinも__stdinpとかになってますね。昔はもっとややこしいマクロだったような...。あとisspace()についてですが、 Cのプログラム #include <stdio.h> #include <ctype.h>
int main() { int c, n = 0; while((c = getchar()) != EOF) { if(isspace(c)) ++n; } printf("n = %d\n", n); return 0; } とC++のプログラム #include <cstdio> #include <cctype>
int main() { int c, n = 0; while((c = getchar()) != EOF) { if(isspace(c)) ++n; } printf("n = %d\n", n); return 0; } で2.4GBのファイルを食わせて有意な差がなかったのですが、関数呼出のせい? 前者 48.54s user 4.74s system 74% cpu 1:11.26 total 後者 48.55s user 4.71s system 76% cpu 1:09.20 total
|
|
|
[90]Re:getchar() へるみ . 2007 11/7(Wed) 9:47
|
>有意な差がなかったのですが while()の中身を空ループにしたらどうなりますかね. ・速度が変わらない →ディスクアクセスに律速されている. ・変わった →getchar()が重い. ・日記のようにfread()でまとめよみに変更してみる.
|
|
|
[91]Re:getchar() dsk . 2007 11/7(Wed) 17:01
|
ぼけてました。 #include <iostream>をしていないからCと同じisspace()が使われているかも?というのはおいといて、
ループが空:32.20s user 5.17s system 56% cpu 1:05.79 total バッファリング: 28.50s user 5.18s system 44% cpu 1:15.09 total
どちらもCです。こりゃDiskかな?
C++バッファリング: 29.57s user 8.23s system 42% cpu 1:29.91 total 28.65s user 5.24s system 47% cpu 1:11.91 total C++バッファリング cctype→iostream:28.65s user 5.24s system 47% cpu 1:11.91 total
ということでこのプログラムではdiskがネックですね。
ということで、8Kだけ読んで10万回繰り返してみました。 C: 1.46s user 0.01s system 99% cpu 1.472 total C++cctype: 1.46s user 0.01s system 99% cpu 1.469 total C++iostream: 2.07s user 0.00s system 99% cpu 2.071 total
ということで、C++のときは#include <cctype> ならCと同じ、#include<iostream>なら遅くなります。両方インクルードすると順序にかかわらず#include<iostream>の場合と同じです。
#include <cstdio> #include <cctype> static inline int my_isspace(int c) { return isspace(c); } #include <iostream>
int main() { int i, r, n = 0; char buf[8192]; fread(buf, 1, sizeof buf, stdin); for(r = 0; r < 100000; ++r) { for(i = 0; i < sizeof buf; ++i) { if(my_isspace(buf[i])) ++n; } } printf("n = %d\n", n); return 0; }
とか #include <cstdio> extern int isspace(int); #define isspace my_isspace #include <cctype> #include <iostream>
int main() { int i, r, n = 0; char buf[8192]; fread(buf, 1, sizeof buf, stdin); for(r = 0; r < 100000; ++r) { for(i = 0; i < sizeof buf; ++i) { if(my_isspace(buf[i])) ++n; } } printf("n = %d\n", n); return 0; }
とか小賢しいことやってみても遅い方でした。何度か実験しても小数第2位くらいまで同じ値になります。ですのでC++でiostreamを利用する場合、isspace()呼出を含む処理速度がクリティカルになる関数は分離して#include<iostream>ではなく#include<cctype>すべきである、ということですね。
|
|
|
[94]isspace egtra . 2007 11/15(Thr) 21:56
|
|
|
|
[95]Re:getchar() へるみ . 2007 11/17(Sat) 10:31
|
|
情報ありがとうございます.古くから知られていることなのですね.私ももう一度調べてみます.
|
|
|
|