浅析不同编程语言多种输入输出方式的时间效率

lr580 发表于 2年前 · 关联问题 快读/快写

广告: 该部分内容改编自我的算法模板,想查看更多算法知识/代码欢迎点击 这里

SCNUOJ1728-快读/快写 为例下面对 C++, Python, Java 多种读入/输出方式进行探讨

本题是 5\times10^6 的输入和 5\times10^5 的输出 (我也想造更大的输出,但是 OJ 会说我输出超限 QwQ)

目录:

C++

朴素 cin/cout

BUFF: 不关同步流,不使用 cin.tie(0),不使用 cout.tie(0),不替换 endl

战绩:TLE (4490ms)

#include <bits/stdc++.h> using namespace std; #define sc(x) scanf("%lld", &x) typedef long long ll; ll n; signed main() { cin >> n; while (n) { ll m = min(10LL, n); ll x, sum = 0; for (ll i = 1; i <= m; ++i) { cin >> x; sum += x; } n -= m; cout << sum << endl; } return 0; }

关闭同步流 cin/cout

BUFF: 关同步流,不使用 cin.tie(0),不使用 cout.tie(0),不替换 endl (用 \n 替换了也几乎没区别)

战绩:TLE (3974ms)

#include <bits/stdc++.h> using namespace std; #define sc(x) scanf("%lld", &x) typedef long long ll; ll n; signed main() { ios::sync_with_stdio(false); cin >> n; while (n) { ll m = min(10LL, n); ll x, sum = 0; for (ll i = 1; i <= m; ++i) { cin >> x; sum += x; } n -= m; cout << sum << endl; } return 0; }

开启cin.tie(0)、替换 endl

BUFF: 关同步流,使用 cin.tie(0),不使用 cout.tie(0)\n替换 endl (不用 \n 替换几乎没区别,反而更慢)

战绩:326ms

如果开 cout.tie(0) 但不开 cin.tie(0) ,无论替不替换 endl 都没区别

在开 cin.tie(0) 的情况下,不论开不开 cout.tie(0) 都没什么区别,但是一定要用 \n替换 endl ,不然都会 TLE

#include <bits/stdc++.h> using namespace std; #define sc(x) scanf("%lld", &x) typedef long long ll; ll n; signed main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n; while (n) { ll m = min(10LL, n); ll x, sum = 0; for (ll i = 1; i <= m; ++i) { cin >> x; sum += x; } n -= m; cout << sum << '\n'; } return 0; }

朴素 scanf/printf

战绩:454 MS

#include <bits/stdc++.h> using namespace std; #define sc(x) scanf("%lld", &x) typedef long long ll; ll n; signed main() { sc(n); while (n) { ll m = min(10LL, n); ll x, sum = 0; for (ll i = 1; i <= m; ++i) { sc(x); sum += x; } n -= m; printf("%lld\n", sum); } return 0; }

普通快读快写

战绩:155MS

如果用位运算优化快读(代码见下文,可以稍微优化到146MS)

如果再使用快写优化(代码见下文,可以稍微优化到133MS)

#include <bits/stdc++.h> using namespace std; typedef long long ll; ll read() { ll num = 0; char c = getchar(), up = c; while (c < '0' || c > '9') up = c, c = getchar(); while (c >= '0' && c <= '9') num = (num << 1) + (num << 3) + (c ^ '0'), c = getchar(); return up == '-' ? -num : num; } #define sc(x) x = read() ll n; signed main() { sc(n); while (n) { ll m = min(10LL, n); ll x, sum = 0; for (ll i = 1; i <= m; ++i) { sc(x); sum += x; } n -= m; printf("%lld\n", sum); } return 0; }

位运算优化:

ll read() { char p = 0; ll r = 0, o = 0; for (; p < '0' || p > '9'; o |= p == '-', p = getchar()) ; for (; p >= '0' && p <= '9'; r = (r << 1) + (r << 3) + (p ^ 48), p = getchar()) ; return o ? (~r) + 1 : r; }

快写:

#include <bits/stdc++.h> using namespace std; typedef long long ll; ll read() { char p = 0; ll r = 0, o = 0; for (; p < '0' || p > '9'; o |= p == '-', p = getchar()) ; for (; p >= '0' && p <= '9'; r = (r << 1) + (r << 3) + (p ^ 48), p = getchar()) ; return o ? (~r) + 1 : r; } void write(ll x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) { write(x / 10); } putchar(x % 10 + '0'); } #define sc(x) x = read() ll n; signed main() { sc(n); while (n) { ll m = min(10LL, n); ll x, sum = 0; for (ll i = 1; i <= m; ++i) { sc(x); sum += x; } n -= m; write(sum), putchar('\n'); } return 0; }

究极快读快写

战绩:37MS

#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll MAXSIZE = 1 << 20; char buf[MAXSIZE], *p1, *p2; #define gc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin), p1 == p2) ? EOF : *p1++) inline ll rd() { ll x = 0, f = 1; char c = gc(); while (!isdigit(c)) { if (c == '-') f = -1; c = gc(); } while (isdigit(c)) x = x * 10 + (c ^ 48), c = gc(); return x * f; } char pbuf[1 << 20], *pp = pbuf; inline void push(const char &c) { if (pp - pbuf == 1 << 20) fwrite(pbuf, 1, 1 << 20, stdout), pp = pbuf; *pp++ = c; } inline void write(ll x) { if (x < 0) x = -x, push('-'); static ll sta[35]; ll top = 0; do { sta[top++] = x % 10, x /= 10; } while (x); while (top) push(sta[--top] + '0'); } ll n; signed main() { n = rd(); while (n) { ll m = min(10LL, n); ll x, sum = 0; for (ll i = 1; i <= m; ++i) { x = rd(); sum += x; } n -= m; write(sum), push('\n'); } fwrite(pbuf, 1, pp - pbuf, stdout); return 0; }

Python

朴素读写

战绩:TLE(推测14000ms) (即使是 2\times10^4 的数据量也需要 174MS)

n = int(input()) // 10 for i in range(n): s = 0 for j in range(10): s += int(input()) print(s)

快读

战绩:1408MS (在 2\times10^4 的数据量需要 20MS, 估算快了十倍)

import sys input = sys.stdin.readline n = int(input()) // 10 for i in range(n): s = 0 for j in range(10): s += int(input()) print(s)

使用快写没有显著的优化:(1407MS)

import sys input = sys.stdin.readline print = sys.stdout.write n = int(input()) // 10 for i in range(n): s = 0 for j in range(10): s += int(input()) print(str(s) + '\n')

JAVA

朴素读写

战绩:4648MS

import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt() / 10; for (int i = 0; i < n; ++i) { int s = 0; for (int j = 0; j < 10; ++j) { s += sc.nextInt(); } System.out.println(s); } sc.close(); } }

快读

战绩:2419MS

import java.io.*; public class Main { static StreamTokenizer scanner = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); // static PrintWriter out = new PrintWriter(new BufferedWriter(new // OutputStreamWriter(System.out))); public static int nextInt() throws IOException { scanner.nextToken(); return (int) scanner.nval; } public static void main(String[] args) throws IOException { int n = nextInt() / 10; for (int i = 0; i < n; ++i) { int s = 0; for (int j = 0; j < 10; ++j) { s += nextInt(); } System.out.println(s); } } }

快读快写

战绩:679MS

import java.io.*; public class Main { static StreamTokenizer scanner = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out))); public static int nextInt() throws IOException { scanner.nextToken(); return (int) scanner.nval; } public static void main(String[] args) throws IOException { int n = nextInt() / 10; for (int i = 0; i < n; ++i) { int s = 0; for (int j = 0; j < 10; ++j) { s += nextInt(); } out.println(s); } out.close(); } }

嗞磁(话说原来关同步+cin.tie(0)+cout.tie(0)比scanf快(