LOADING

加载过慢请开启缓存 浏览器默认开启

建议搭配 steam++ 食用更佳

『小祭巧』什么是 FastIO , 我说...

必要性

总所周知 , 在毒瘤大数据面前 , scanf/printf 很慢 , cin/cout 更慢 . 所以目前有两种主流的快读快写 , getchar/putchar ( putchar 有时甚至不如 printf ) 和 解绑 ios .

至于 cin/cout ( 不解绑的情况下 ) 为什么慢 , 这里不多阐述 ( 也相信你点进来不是为了这个 ) .

顺便一提 , 在某些评测姬上 , 解绑 cin/cout 特别能吃 $buff$ , 在处理字符上比 fread/fwrite 快了不知道多少 . $→$ 刷题时 $2e7$ 范围的字符 , $T$ 了三个点 , 后来才发现是 fread/fwrite慢啦 !


$\text{速度比较}$

$\text{输入}$

$n = 1e9$ , 采用 $mt19937$ 生成随机数 , 保证所有数据在 int 范围内 , 三次取最快 , 保留 $3$ 位小数 .

冷笑话 : $10.3G$ ( $1e9$ ) 的数据把我可怜的 $16G$ 内存条干爆了 ( 后来用浏览器打开的 ) .

cin : 876.288s
scanf : 335.884s
getchar : 159.953s
解绑cin : 87.893s
fread : 38.521s

显而易见的 , fread 占据了上风 . 另外 , 值得注意的是 : getchar解绑cin ( 本文后面将不再讨论 cin/coutscanf 的速度差异 , 并且后文将简称 cin/cout解绑cin/cout ) 差了 $2$ 倍左右 . 而将 cin 解绑仅需要一行 :

ios::sync_with_stdio(NULL),cin.tie(NULL),cout.tie(NULL);
// NULL 可以替换为 0 , 这里用 NULL 只是习惯的问题 .

getchar 在不压行的情况下比 cin 多得多 :

template <typename T>
inline auto Read(T &variable) -> void {
    variable = 0;
    bool negative = false;
    char charact;
    do {
        charact = getchar();
        negative ^= charact == '-';
    }while(!isdigit(charact));
    while(isdigit(charact)) {
        variable = (variable << 1) + (variable << 3) + (charact ^ 0x30);
        charact = getchar();
    }
    if(negative) variable = ~variable + 1;
}
// 其实可以更短 , 但是个人感觉这样写更好看些 ( 雾

所以 , 在背不到 fread/fwrite 的模板时 , cin/cout 才是永远的神 .

再来看一组较小的数据 ( 毕竟没有哪道题会出这么毒瘤良心的数据来恶心人 , 所以还是把数据放正常点 ) .

$n = 1e7$ , 其余条件与 $n = 1e9$ 时一样 .

getchar : 1.610s
cin : 0.880s
fread : 0.392s

可以看到 , 这次 getcharcin 慢了 $2$ 倍不止 .

那么 , 再见 , getchar .

$\text{输出}$

printf :
putchar (递归) :
putchar (栈) :
cout :
fwrite :

$\text{附录}$

$\text{测试环境}$

处理器    12th Gen Intel(R) Core(TM) i9-12900H   2.50 GHz
机带 RAM    16.0 GB (15.7 GB 可用)
系统类型    64 位操作系统, 基于 x64 的处理器
版本    Windows 11 家庭中文版
版本    22H2
操作系统版本    22621.1702
体验    Windows Feature Experience Pack 1000.22641.1000.0