直观比较读入的效率

数据生成

数据

随机生成一个长度为 \(5\times 10^7\) ,值域在 \([0,500)\) 的数列。

数据生成器

int main() {
  srand(time(NULL));
  freopen("1.in", "w", stdout);
  for (int i = 1; i <= 50000000; i++) {
    printf("%d ", rand() % 500);
  }
}

对比

以下所有测试均在 -std=c++11,-O2,-O3 下进行。

cin

const int N = 50000005;
int a[N], n = 50000000;
int main() {
  freopen("1.in", "r", stdin);
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
}

cin 关同步流

const int N = 50000005;
int a[N], n = 50000000;
int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  freopen("1.in", "r", stdin);
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
}

scanf

const int N = 50000005;
int a[N], n = 50000000;
int main() {
  freopen("1.in", "r", stdin);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
  }
}

快读

const int N = 50000005;
int a[N], n = 50000000;
int read() {
  int x = 0;
  char ch = getchar();
  while (ch < '0' || ch > '9') ch = getchar();
  while ('0' <= ch && ch <= '9') x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); 
  return x;
}
int main() {
  freopen("1.in", "r", stdin);
  for (int i = 1; i <= n; i++) {
    a[i] = read();
  }
}

快读 + isdigit

const int N = 50000005;
int a[N], n = 50000000;
int read() {
  int x = 0;
  char ch = getchar();
  while (!isdigit(ch)) ch = getchar();
  while (isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); 
  return x;
}
int main() {
  freopen("1.in", "r", stdin);
  for (int i = 1; i <= n; i++) {
    a[i] = read();
  }
}

inline + 快读 + isdigit

const int N = 50000005;
int a[N], n = 50000000;
inline int read() {
  int x = 0;
  char ch = getchar();
  while (!isdigit(ch)) ch = getchar();
  while (isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); 
  return x;
}
int main() {
  freopen("1.in", "r", stdin);
  for (int i = 1; i <= n; i++) {
    a[i] = read();
  }
}

fread

const int N = 50000005;
int a[N], n = 50000000;
char buf[1 << 21], *p1 = buf, *p2 = buf;
int getc() {
  return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF: *p1++;
}
int read() {
  int x = 0;
  char ch = getc();
  while (!isdigit(ch)) ch = getc();
  while (isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getc();
  return x;
}
int main() {
  freopen("1.in", "r", stdin);
  for (int i = 1; i <= n; i++) {
    a[i] = read();
  }
}

sgetn

const int N = 50000005;
int a[N], n = 50000000;

const int B = 1 << 21;
char Obuf[B], Ibuf[B];
char *optr = Obuf, *ist = 0, *ied = 0;
streambuf *out, *in;
void print(char c) {
  optr == Obuf + B ? (out->sputn(Obuf, B), optr = Obuf), *optr++ = c : *optr++ = c;
}
void flush() {
  out->sputn(Obuf, optr - Obuf);
}
char getc() {
  return ist == ied ? ied = Ibuf + in->sgetn(ist = Ibuf, B), (ist == ied ? -1 : *ist++) : *ist++;
}
int read() {
  int x = 0;
  char ch = getc();
  while (!isdigit(ch)) ch = getc();
  while (isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getc();
  return x;
}
int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  in = cin.rdbuf(), out = cout.rdbuf();
  freopen("1.in", "r", stdin);
  for (int i = 1; i <= n; i++) {
    a[i] = read();
  }
}

mmap

#include <bits/stdc++.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
using namespace std;

const int N = 50000005;
int a[N], n = 50000000;

char *pc;
int read() {
  int x = 0;
  char ch = *pc++;
  while (!isdigit(ch)) ch = *pc++;
  while (isdigit(ch)) x = (x << 3) + (x << 1) + ch - '0', ch = *pc++;
  return x;
}

int main() {
  pc = (char *) mmap(NULL, lseek(0, 0, SEEK_END), PROT_READ, MAP_PRIVATE, 0, 0);
  freopen("1.in", "r", stdin);
  for (int i = 1; i <= n; i++) {
    a[i] = read();
  }
}

对比表

读入方式 实验1/s 实验2/s 实验3/s 平均用时/s 效率排名
\(\texttt{cin}\) \(23.890s\) \(23.990s\) \(23.820s\) \(23.900s\) \(9\)
\(\texttt{scanf}\) \(20.490s\) \(20.310s\) \(20.350s\) \(20.383s\) \(8\)
\(\texttt{cin}\) 关同步流 \(5.936s\) \(5.970s\) \(5.862s\) \(5.923s\) \(7\)
快读 \(4.601s\) \(4.670s\) \(4.666s\) \(4.646s\) \(6\)
快读 + \(\texttt{isdigit}\) + \(\texttt{inline}\) \(4.626s\) \(4.616s\) \(4.589s\) \(4.610s\) \(5\)
快读 + \(\texttt{isdigit}\) \(4.627s\) \(4.569s\) \(4.611s\) \(4.602s\) \(4\)
\(\texttt{fread}\) \(0.546s\) \(0.558s\) \(0.547s\) \(0.550s\) \(3\)
\(\texttt{sgetn}\) \(0.535s\) \(0.542s\) \(0.541s\) \(0.539s\) \(2\)
\(\texttt{mmap}\) [N/A] [N/A] [N/A] [N/A] 理论 \(1\)

第二次测速 (2021.05.19)

三组数据,分别 \(n=10^6,10^7,5\times 10^7\) ,值域 \([0,2^{20})\)

cin 关同步流:

data #1, in = read1.in, out = read1.out, statu = Accepted, time used = 0.240 s.
data #2, in = read2.in, out = read2.out, statu = Accepted, time used = 1.698 s.
data #3, in = read3.in, out = read3.out, statu = Accepted, time used = 8.299 s.

快读 + \(\texttt{isdigit}\)

data #1, in = read1.in, out = read1.out, statu = Accepted, time used = 0.258 s.
data #2, in = read2.in, out = read2.out, statu = Accepted, time used = 1.827 s.
data #3, in = read3.in, out = read3.out, statu = Accepted, time used = 8.781 s.

\(\texttt{fread}\)

data #1, in = read1.in, out = read1.out, statu = Accepted, time used = 0.118 s.
data #2, in = read2.in, out = read2.out, statu = Accepted, time used = 0.297 s.
data #3, in = read3.in, out = read3.out, statu = Accepted, time used = 1.115 s.

\(\texttt{sgetn}\)

data #1, in = read1.in, out = read1.out, statu = Accepted, time used = 0.092 s.
data #2, in = read2.in, out = read2.out, statu = Accepted, time used = 0.254 s.
data #3, in = read3.in, out = read3.out, statu = Accepted, time used = 1.043 s.
posted @ 2020-07-15 21:18  wlzhouzhuan  阅读(527)  评论(0编辑  收藏  举报