UPD20191125:我發現我又丟人了,sgetc只會讀取緩沖區當前字符而不會前移讀取位置,想要讀取並前移讀取位置應該用sbumpc。。。
一般情況下,在C++中,iostream內的cin和cout是比scanf和printf慢的,這主要是為了同時兼容iostream和stdio,iostream與stdio的緩沖區被綁到了一起,以及cin和cout的stream是綁定在一起的,這使得cin和cout有額外的開銷
為了提高cin和cout的效率,我們可以取消iostream與stdio的同步,以及cin和cout的stream的綁定:
1 std::ios::sync_with_stdio(false); 2 cin.tie(NULL); 3 cout.tie(NULL);
這樣cin與cout就比scanf和printf快了。在本機測試上,iostream甚至比stdio快了6倍左右。然而這樣做之后,就不可以將iostream與stdio混用了,然而輸入量較大的時候,這種方法仍然無能為力
在stdin中,我們有getchar,想要追求更快的速度,我們有fread
在iostream中我們同樣可以達到同樣的效率,甚至更快:
首先要獲取cin的streambuf:
std::streambuf *fb = cin.rdbuf();
然后我們就可以進行類似stdio中的操作:
對於getchar,我們有sbumpc,它的用法等同於getchar,速度略快於getchar:
char ch = fb -> sbumpc();
對於fread,我們有sgetn,它的用法與fread類似,速度略快於fread:
#define MAX_INPUT 1000000 char buf[MAX_INPUT] int main() { fb -> sgetn(buf, MAX_INPUT); return 0; }
輸入問題就解決了。還有輸出問題:
(不知道為什么,網上的輸出代碼在我這邊不會進行輸出,然而我這邊手寫的輸出比fwrite慢了好多。。。。)
對於putchar,我們有sputc,它的用法等同於putchar,速度略快於putchar:
char ch = '\n'; fb -> sputc(ch);
對於fwrite,我們有sputn,它的用法與fwrite類似,速度略快於fwrite?
#define MAX_OUTPUT 1000000 char buf[MAX_OUTPUT]; int main() { fb -> sputn(buf, MAX_OUTPUT); return 0; }
這樣我們就有了一份完整的快速輸入輸出 丟人 代碼(因為sputn的那份比sputc還慢,所以這里就用了sputc的代碼):
#include<iostream> #include<cctype> using std::cin; using std::cout; using std::endl; namespace IN { #define MAX_INPUT 1000000 #define cinchar() ((fs == ft && (ft = (fs = buf) + fb -> sgetn(buf, MAX_INPUT))) ? 0 : *fs++) char buf[MAX_INPUT], *fs, *ft; inline int read() { static std::streambuf *fb = cin.rdbuf(); register int x = 0; register bool f = false; register char ch = cinchar(); while (!isdigit(ch)) { if (ch == '-') f = true; ch = cinchar(); } while (isdigit(ch)) { x = (x << 1) + (x << 3) + ch - '0'; ch = cinchar(); } return f ? -x : x ; } #undef MAX_INPUT #undef cinchar } namespace OUT { inline void put(int x) { static std::streambuf *fb = cout.rdbuf(); static char stack[11]; static int top = 0; if (!x) { fb -> sputc('0'); fb -> sputc('\n'); return; } while (x) { stack[++top] = x % 10 + '0'; x /= 10; } while (top) { fb -> sputc(stack[top]); --top; } fb -> sputc('\n'); } } int main() { freopen("add.in", "r", stdin); std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int a = IN::read(), b = IN::read(); OUT::put(a + b); return 0; }
為了丟人,在這里貼上sputn的代碼

1 namespace OUT { 2 #define MAX_OUTPUT 1000000 3 char buf[MAX_OUTPUT], *fs = buf, *ft = buf + MAX_OUTPUT; 4 #define coutchar(ch) *fs++ = ch 5 inline void put(int x) { 6 static std::streambuf *fb = cout.rdbuf(); 7 static char stack[11]; 8 static int top = 0; 9 if (!x) { 10 coutchar('0'); coutchar('\n'); 11 return; 12 } 13 while (x) { 14 stack[++top] = x % 10 + '0'; 15 x /= 10; 16 } 17 while (top) { 18 *fs++ = stack[top]; 19 --top; 20 } 21 coutchar('\n'); 22 fb -> sputn(buf, fs - buf); 23 fs = buf; 24 } 25 #undef coutchar 26 #undef MAX_OUTPUT 27 }
代碼部分參考自:https://blog.csdn.net/simpsonk/article/details/78457842