C++ã®streamã®è»¢éé度ã調ã¹ã
ã¯ããã«
C++ã®streamã¯ã¨ã¦ãè¯ãã§ãã¦ãã¦ããããç¨ããã©ã¤ãã©ãªãä½ãããã®ã ãã©ã
æ¬å½ã«(主ã«ããã©ã¼ãã³ã¹çãªçç±ã§)大ä¸å¤«ãªã®ã¨ããããã話ã
åãã«ãæããã¦ããã¾ããã以ä¸ã®å
容ã¯ãã¹ã¦linux+gcc4.3ã§ã®è©±ã§ãã
streamã¯é ã
ãµã¤ãã«istreamããget()ãã¦ãostreamã«putãã¦ãã¨ãã¡ããã¡ãé
ãã
Cè¨èªã®getchar, putcharãã10é²æ°ã§1.5æ¡ãããé
ããã
istream::readã¨ãã§ã§ãããããã¯èªãã°å¤§ä¸å¤«ãªã®ã ãã©ã
ç´°ããåä½ã§èªã¿ãããã¨ã®æ¹ãå¤ãããã
ããããããã§ãããããå ´åã«ãéã転éãããã¨ãå¯è½ãªã®ãã©ãã調ã¹ã¦ã¿ãã
ãã¹ãããã°ã©ã
istreamã®å 容ãostreamã«è»¢éããããã°ã©ã ã6éãæ¸ããã
ãã®ï¼ï¼æ®éã®ããã°ã©ã
ãªã¼ã½ããã¯ã¹ãªããã°ã©ã ã
void copy1(ostream &os, istream &is) { for (char c; is.get(c); os<<c); }
ãã®ï¼ï¼ãããã¯ãã¨ã«èªã¿æ¸ã
ä»åã®è¶£æ¨ã«ã¯ä¼ããªããé度ã®æ¯è¼ã®ããã
(readã«å¤±æããã¨ãã®å¦çããã£ã¦ãã®ãä¸æ)
void copy2(ostream &os, istream &is) { for (;;){ char buf[1024]; if (!is.read(buf, 1024)) break; os.write(buf, 1024); } copy1(os, is); }
ãã®ï¼ï¼istream_iteratorã使ã
is>>c; os<
void copy3(ostream &os, istream &is) { istream_iterator<char> p(is), end; ostream_iterator<char> q(os); copy(p, end, q); }
ãã®ï¼ï¼istreambuf_iteratorã使ã
Effective STLããããã®æ¹æ³ã
空ç½ã¯å¤§ä¸å¤«ã§ãã
void copy4(ostream &os, istream &is) { istreambuf_iterator<char> p(is), end; ostreambuf_iterator<char> q(os); copy(p, end, q); }
ãã®ï¼ï¼ostreamã«streambufãçªã£è¾¼ã
ããã¾ãæè»æ§ã¯ç¡ããã©ã
ãã®æ¸ãæ¹ãã©ã®ãããã®é度ãªã®ã調ã¹ããã£ãã
void copy5(ostream &os, istream &is)
{
os<<is.rdbuf();
}
ãã®ï¼ï¼istreamããstreambufã«çªã£è¾¼ã
5ã¨åããããã®é度ã«ãªãã¨ããäºæ¸¬ã
void copy6(ostream &os, istream &is)
{
is>>os.rdbuf();
}
å
ã¤æ¸ãããã©ãæå¾
ãã¦ããã®ã¯ãã®4ã ãã§ãã
ãããã©ãããã±ã¼ã¹ã§éããªãã®ãã調ã¹ããã
ãã¹ã
ãããã®ã«ã¼ãã³ããifstream&ofstreamã¨ãcin&coutã
ããã«ããããçµã¿åããã¨ãåºåã/dev/nullã«ãªã£ã¦ãã¨ãã®
è¨8éãã§ãã¹ããåä½ã¯ç§ã
ãã¡ã¤ã«ãµã¤ãºã¯1GBã
ã¡ã¢ãª8GBã®ãã·ã³ã«ããã¦å®è¡ã
ãã¡ã¤ã«ã®å
容ã¯ãã£ãã·ã¥ã«ãã¹ã¦ä¹ã£ãç¶æ³ã§ãã®ã§ã
ç´ç²ã«CPUã®è¨ç®éã®ã¿ãèæ
®ããããã®ã¨èãã¦ãã ããã
file -> file(æ®éã®ãã¡ã¤ã«)
copy1 | 40.310 |
copy2 | 3.340 |
copy3 | 46.900 |
copy4 | 1.550 |
copy5 | 1.870 |
copy6 | 1.620 |
file -> file(/dev/null)
copy1 | 38.610 |
copy2 | 0.880 |
copy3 | 45.390 |
copy4 | 0.400 |
copy5 | 0.390 |
copy6 | 0.410 |
file -> stdout(æ®éã®ãã¡ã¤ã«ã«ãªãã¤ã¬ã¯ã)
copy1 | 47.780 |
copy2 | 3.560 |
copy3 | 53.990 |
copy4 | 3.330 |
copy5 | 4.120 |
copy6 | 4.060 |
file -> stdout(/dev/nullã«ãªãã¤ã¬ã¯ã)
copy1 | 56.530 |
copy2 | 0.700 |
copy3 | 66.580 |
copy4 | 0.510 |
copy5 | 0.500 |
copy6 | 0.510 |
stdin -> file
copy1 | 69.860 |
copy2 | 3.390 |
copy3 | 98.580 |
copy4 | 34.540 |
copy5 | 35.980 |
copy6 | 34.880 |
stdin -> /dev/null
copy1 | 68.000 |
copy2 | 0.890 |
copy3 | 100.190 |
copy4 | 34.180 |
copy5 | 34.040 |
copy6 | 34.410 |
stdin -> stdout(file)
copy1 | ã¨ã¦ãé·ã(>300) |
copy2 | 6.080 |
copy3 | ã¨ã¦ãé·ã |
copy4 | 46.160 |
copy5 | 70.310 |
copy6 | 70.530 |
stdin -> stdout(/dev/null)
copy1 | ã¨ã¦ãé·ã |
copy2 | 0.870 |
copy3 | ã¨ã¦ãé·ã |
copy4 | 44.830 |
copy5 | 44.210 |
copy6 | 44.350 |
ã¨ã¦ãé·ãã¨æ¸ãã¦ããã¨ããã¯ãé·ãããã®ã§åãã¾ããã
5åã§åãã¾ããããå¤å10åãã£ã¦ãããããªãã®ãããªãããªã
èå¯
åºåã/dev/nullãæ®éã®ãã¡ã¤ã«ãã¯å½ç¶/dev/nullã®æ¹ãéããã®ã®ã
systemã®æéãå¤ããã ãã§ãã
è¨æ¸¬ããå¿
è¦ãªãã£ããªã
ãããã¯è»¢é(copy2)ã¯ãã¹ã¦ã«ããã¦éãã
ãããå½ç¶ãªããã
copy1ã¯ãã¹ã¦ã«ããã¦é
ãã
å½ç¶ãªããã»ã¨ãã©useræéã
copy4,5,6ã¯åããããã®é度ã«ãªã£ãã
streambuf_iteratorã ãé
ãã¨ããçµæã«ãªããªãã¦ããã£ãã
æ¨æºå
¥å->æ¨æºåºåã§4ã¨5,6ã§çµæãã ãã¶éãåå ã¯ä¸æã
以ä¸ã¯streambuf_iteratorã«ã¤ãã¦ã
å
¥åãifstreamã®æã¯ãããªã¹ã¦éãã
å
¥åãcinã®æã¯éããªãã
ã§ããcin.get()ã¨ãã§èªã¿åãããã¯éãã
åºåã¯ofstreamã§coutã§ã大差ã¯ãªãã
ã©ã¡ããã¨ããã¨ofstreamã使ãæ¹ãéãããã ã
cin, coutãå®éã©ãããåã«ãªã£ã¦ããã®ãã¯ç¥ããªããã
ã¾ãå®è£
ãfstreamã¨éãã®ã ããã
é度ã®éãã®çç±ã調ã¹ããããstraceãããã¦ã¿ãã
åºæ¬çã«ã©ããããç¨åº¦ã¾ã¨ã¾ã£ã¦read/writeããã¦ããã
(ãµã¤ãºã¯8KB,4KB,1KBæ§ã
ã ã)
ã¤ã¾ããé度ã®éãã¯ãã以å¤ã®ãªã¼ãã¼ãããã§ããã
ãããã許容ããããã»ã©é
ãã£ããã®(cin->coutã®copy1,3)ã¯
åºåãä¸æåãã¤writeããã¦ããã
ããã¯å¦ä½ã«ã
ãã¡ã¤ã«ããcoutã¸è»¢éããå ´åãå度調ã¹ããã
ãããã«ãããã¡ãªã³ã°ããã¦ããã
åãcoutã¸ã®åºåãªã®ã«ãªãï¼
調ã¹ãããã«ã次ã®2ã¤ã®ã³ã¼ããæ¸ããã
for (char c; cin.get(c); ) cout<<c;
ifstream ifs("tmp"); for (char c; ifs.get(c); ) cout<<c;
ããã¨ããã¯ãããªãã¨ãåè
ã¯ãããã¡ãªã³ã°ããããå¾è
ã¯ãããã®ã ã
ç§ã¯ãã®çµæãè¦ãã¨ãã
ããC++ã¨ã¯ã¨ã£ã¨ã¨ãããã°ãã¦ã¦ã¼ããã¢ã¸è¡ããï¼
ã¨æããã«ã¯ããããªãã£ãã
ä»åãã®åå ãæ¢ãã®ã¯ããã©ãã®ã§ããªããã
ã¾ããã®ãã¡èª¿ã¹ããã¨æããã¨ãããã調ã¹ãªãã¨ãããã®ã ãããªãã
read/writeã¨ã®æ¯è¼
FDéã§ç´æ¥è»¢éããå ´åã¨æ¯ã¹ã¦ã©ããªã®ãã調ã¹ã¦ã¿ãã
void fdcopy(int to, int from) { char buf[1024*8]; for (int n; (n=read(from, buf, sizeof(buf)))>0; ){ char *p=buf, *q=p+n; while(p<q){ ssize_t ret=write(to, p, q-p); assert(ret>0); p+=ret; } } }
çµæ
file-> file | 1.280 |
file -> /dev/null | 0.390 |
stdin -> stdout | 2.430 |
stdin -> stdout(/dev/null) | 0.380 |
streambuf_iteratorã®ãªã¼ãã¼ãããã¯1å²ç¨åº¦ã¨è¨ããã¨ã«ãªãã
(ãããã¡ã®ãµã¤ãºãéã£ããããã®ã§ãåç´ã«ã¯è¨ããªããã©ã)
ã¾ã¨ã
ã¾ã¨ãã¦èªããã¨ãå¯è½ãªããistream::read(), ostream::write()ã使ããã
cinããã®istreambuf_iteratorçµç±ã§ã®å
¥åã¯ãã¾ãéããªãã
ã§ããget()ãªã©ãå¼ã¶ãã¨ã«æ¯ã¹ããéãã
ifstreamããã®istreambuf_iteratorã¯ã¨ã¦ãéãã
ostreambuf_iteratorã¯å¤§ä½ã¨ã¦ãéãã
çµè«ã¨ãã¦ã¯ãstreambuf_iteratorã¯ååéããåå使ããã
ã¤ã¾ããstream使ã£ã¨ãã¦å¤§ä¸å¤«ã