【发布时间】:2012-08-06 05:50:51
【问题描述】:
我正在做这样的事情:
for (int i = 0; i < 100000; i++) {
System.out.println( i );
}
基本上,我计算一个整数并输出一个字符串大约 10K-100K 次,然后需要将结果写入 system.out,每个结果用换行符分隔。
实现这一目标的最快方法是什么?
【问题讨论】:
-
尝试几种方法并分析它们。
标签: java
我正在做这样的事情:
for (int i = 0; i < 100000; i++) {
System.out.println( i );
}
基本上,我计算一个整数并输出一个字符串大约 10K-100K 次,然后需要将结果写入 system.out,每个结果用换行符分隔。
实现这一目标的最快方法是什么?
【问题讨论】:
标签: java
感谢您的建议。我创建了一个测试程序来比较它们:
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.StringBuilder;
public class systemouttest {
public static void main(String[] args) throws Exception {
long starttime = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
System.out.println( i );
}
long printlntime = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100000; i++) {
sb.append( i + "\n" );
}
System.out.print(sb.toString());
long stringbuildertime = System.currentTimeMillis();
OutputStream out = new BufferedOutputStream ( System.out );
for (int i = 0; i < 100000; i++) {
out.write((i + "\n").getBytes());
}
out.flush();
long bufferedoutputtime = System.currentTimeMillis();
BufferedWriter log = new BufferedWriter(new OutputStreamWriter(System.out));
for (int i = 0; i < 100000; i++) {
log.write(i + "\n");
}
log.flush();
long bufferedwritertime = System.currentTimeMillis();
System.out.println( "System.out.println: " + (printlntime - starttime) );
System.out.println( "StringBuilder: " + (stringbuildertime - printlntime) );
System.out.println( "BufferedoutputStream: " + (bufferedoutputtime - stringbuildertime) );
System.out.println( "BufferedWriter: " + (bufferedwritertime - bufferedoutputtime) );
}
}
结果:
环境1
System.out.println: 482
字符串生成器:210
缓冲输出流:86
BufferedWriter:202
环境2
System.out.println: 1763
字符串生成器:45
缓冲输出流:76
BufferedWriter:34
这些建议都比 System.out.println 执行得更好。 BufferedOutputStream 似乎是最安全的选择,因为它在两种测试环境中都表现良好。不过 BufferedWriter 可能更快。
如果有人有任何想法,请发表进一步的建议。我相信有人可以让它更快:)
【讨论】:
对于大量数据,System.out.println 可能效率低,因为它不会
做很好的缓冲。在这种情况下,您可以使用BufferedOutputStream 或BufferedWriter。
【讨论】:
请记住,与内存中的处理相比,I/O 操作非常慢(例如解析整数)。 所以,我建议你“提前”创建整个字符串,然后只打印一次(当然如果可能的话):
StringBuilder sb = new StringBuilder();
for(int i = 0 ; i < 100000; i++) { sb.append(i).append("\n");}
String printMe = sb.toString();
System.out.println(printMe);
有多种技术,例如缓冲您正在使用的输出流的级别,但我假设您更喜欢使用最基本的System.out.println
希望对你有帮助
【讨论】:
Integer.toString(int) 而不是使用 Integer.parseInt(String)
这也包括快速输入和输出方法
import java.io.*;
public class templa{
static class FastReader
{
BufferedReader br;
StringTokenizer st;
public FastReader()
{
br = new BufferedReader(new
InputStreamReader(System.in));
}
String next()
{
while (st == null || !st.hasMoreElements())
{
try
{
st = new StringTokenizer(br.readLine());
}
catch (IOException e)
{
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt()
{
return Integer.parseInt(next());
}
long nextLong()
{
return Long.parseLong(next());
}
double nextDouble()
{
return Double.parseDouble(next());
}
String nextLine()
{
String str = "";
try
{
str = br.readLine();
}
catch (IOException e)
{
e.printStackTrace();
}
return str;
}
}
public static void main(String...args) throws Exception {
OutputStream outputStream =System.out;
PrintWriter out =new PrintWriter(outputStream);
FastReader in =new FastReader();
int testcase = in.nextInt();
while(testcase-- >0){
//in object works same as Scanner Object but much faster
//out.println() works faster than System.out.println()
//Write your code here
}
out.close();
}
}
【讨论】:
写入 System.out 最慢的部分是显示您正在写入的内容所花费的时间。即,对于您编写的每一行,计算机必须使用字体将信息转换为像素并滚动整行。这比您可能为显示文本所做的工作要多得多。
您可以通过
加快写入控制台的速度【讨论】: