「黑科技」使用 streambuf 加速 iostream

使用 streambuf 使 cin / cout 效率高于 fread / fwrite。
iostream 翻身了!!!

iostream

作为一个 C++ 标准库,如果各项功能都赶不上 C 语言的 IO,那还要它有何用?
cin 和 cout 在 OI 中几乎是公认的慢了,但是这其实是使用的问题所造成的。

sync

首先解除 iostream 与 C IO 的绑定,然后解除 cin 与 cout 的绑定,这几个操作相信大家都知道了。

1
2
3
std::ios::sync_with_stdio(false);
std::cin.tie(NULL);
std::cout.tie(NULL);

streambuf

iostream 底层使用了 streambuf,也就是说 cin 和 cout 底层有流缓冲区,我们可以推测导致 cin / cout 慢的原因是对于各种类型的抽取与解析,事实上也是这样。

获取 streambuf

我们首先得拿到 iostream 的 streambuf。

rdbuf

rdbuf 方法返回当前 stream 的 streambuf。

1
std::streambuf *fb = std::cin.rdbuf();

输入

sgetc

sgetc 返回 streambuf 中的下一个字符,用法相当于 getchar,但效率甚至高于 getchar_unlocked。

1
char c = fb->sgetc();
sgetn

sgetn 读入 streambuf 中的 nn 个字符,作用等价于 fread,但效率甚至高于 fread_unlocked。

1
2
3
4
5
6
const int MAXN = 1000000;
char obuf[MAXN];
inline void input() {
fb->sgetn(obuf, MAXN);
}

输出

sputc

sputc 输出一个字符,用法相当于 putchar,但效率甚至高于 putchar_unlocked。

1
2
char c = 't';
fb->sputc(c);
sputn

sputn(buf, n) 输出 buf 中的 nn 个字符,作用等价于 fwrite,但效率甚至高于 fwrite_unlocked。

1
2
3
4
5
6
const int MAXN = 1000000;
char obuf[MAXN];
inline void output() {
fb->sputn(obuf, MAXN);
}

示例

LOJ 110

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
* test std::streambuf and std::cout.rdbuf
* @author xehoth
*/
#include <bits/stdc++.h>
const int OUT_LEN = 10000000;
char obuf[OUT_LEN], *oh = obuf;
std::streambuf *fb;
inline void print(char c) {
oh == obuf + OUT_LEN ? (fb->sputn(obuf, OUT_LEN), oh = obuf) : 0;
*oh++ = c;
}
template <class T>
inline void print(T x) {
static int buf[30], cnt;
for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 | 48;
while (cnt) print((char)buf[cnt--]);
}
inline void flush() { fb->sputn(obuf, oh - obuf); }
#define long long long
const int MAXN = 3000001;
int inv[MAXN];
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(NULL);
std::cout.tie(NULL);
fb = std::cout.rdbuf();
register int n, mod;
std::cin >> n >> mod;
inv[1] = 1;
for (int i = 2; i <= n; i++)
inv[i] = (long)(mod - mod / i) * inv[mod % i] % mod;
for (register int i = 1; i <= n; i++) print(inv[i]), print('\n');
flush();
return 0;
}

文章目录
  1. 1. iostream
  2. 2. sync
  3. 3. streambuf
    1. 3.1. 获取 streambuf
      1. 3.1.1. rdbuf
    2. 3.2. 输入
      1. 3.2.1. sgetc
      2. 3.2.2. sgetn
    3. 3.3. 输出
      1. 3.3.1. sputc
      2. 3.3.2. sputn
  4. 4. 示例