C++ IO 效率实测

Table of Contents

机器配置

硬件型号:Lenovo Lenovo Legion R7000 2021

处理器:AMD® Ryzen 5 5600h with radeon graphics × 12

操作系统:Ubuntu 22.04.1 LTS

测试代码

数据生成器

#include <bits/stdc++.h>
using namespace std;

const int GROUPS = 1e6; // One million
const int LOWLIMIT = 1e4;
const int HIGHLIMIT = 1e7;

inline int getRand(int from, int to) {
    return (rand() % (to - from + 1)) + from;
}

int main(int argc, char const* argv[]) {
    freopen("data.in", "w", stdout);
    srand((unsigned int)(time(NULL)));
    printf("%d\n", GROUPS);
    for (int i = 1; i <= GROUPS; ++i) {
        printf("%d %d\n", getRand(LOWLIMIT, HIGHLIMIT), getRand(LOWLIMIT, HIGHLIMIT));
    }
    return 0;
}

顺便复习了下 C++ 中的随机;当然我知道用取模求得的随机数在分布上并不好……关于随机数这件事之前开了坑,还没填完(

实验代码

统一的框架结构如下

#include <bits/stdc++.h>
using namespace std;

const int GROUPS = 1e7;

int n;
int a[GROUPS + 5][2];

int main(int argc, char const* argv[]) {
    freopen("data.in", "r", stdin);
    freopen("data.out", "w", stdout);
    /* Some code... */
    return 0;
}

cin / cout

    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i][0] >> a[i][1];
    }
    for (int i = 1; i <= n; ++i) {
        cout << a[i][0] << " " << a[i][1] << "\n";
    }

scanf / printf

    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d%d", &a[i][0], &a[i][1]);
    }
    for (int i = 1; i <= n; ++i) {
        printf("%d %d\n", a[i][0], a[i][1]);
    }

cin / cout,关闭同步

    ios::sync_with_stdio(false);
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i][0] >> a[i][1];
    }
    for (int i = 1; i <= n; ++i) {
        cout << a[i][0] << " " << a[i][1] << "\n";
    }

测试数据

time(s) cin cin / cout scanf scanf / printf cin(关闭同步) cin / cout(关闭同步)
direct g++ 0.356 0.468 0.091 0.174 0.091 0.187
with O2 0.351 0.457 0.090 0.164 0.088 0.173

其中,direct g++ 指的是:g++ XXX.cpp -o XXX,with O2 指的是开了 O2 优化。

获取用时的方法是:bash 下用time命令,取real部分时间三次求平均,四舍五入到 0.001s。


Result

点击查看大图

结论

  • 裸 cin / cout 实在是慢的不行
  • 关闭同步后,cin / cout 和 scanf / printf 相差不多(一百万组数据不足以体现)
  • 开启 O2 优化后,用时均有所缩短,幅度不大
  • 输入和输出相比,输入的耗时更长一些

当然,本次测试没有加入快读快写组,测试时间的方法也很草率,精度不高,大体上只是拿个粗浅的结论罢了。

根据我的观察:

Jiangly 的竞赛代码,往往使用的是

std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);

Menci 则是 scanf / printf。

总体来说,both are fast enough and simple enough to use.

Share