java 将字符串输出到系统输出的最快方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11823095/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 06:29:55  来源:igfitidea点击:

What's the fastest way to output a string to system out?

java

提问by CodeSmith

I'm doing something like this:

我正在做这样的事情:

for (int i = 0; i < 100000; i++) {
   System.out.println( i );
}

Basically, I compute an integer and output a string about 10K-100K times and then need to write the result to system.out, each result separated by a newline.

基本上,我计算一个整数并输出大约 10K-100K 次的字符串,然后需要将结果写入 system.out,每个结果由换行符分隔。

What's the fastest way to achieve this?

实现这一目标的最快方法是什么?

回答by CodeSmith

Thank you for the suggestions. I created a test program to compare them:

感谢您的建议。我创建了一个测试程序来比较它们:

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) );
    }

}

Results:

Environment1
System.out.println: 482
StringBuilder: 210
BufferedoutputStream: 86
BufferedWriter: 202

Environment2
System.out.println: 1763
StringBuilder: 45
BufferedoutputStream: 76
BufferedWriter: 34

结果:

Environment1
System.out.println:482
StringBuilder:210
BufferedoutputStream:86
BufferedWriter:202

Environment2
System.out.println:1763
StringBuilder:45
BufferedoutputStream:76
BufferedWriter:34

The suggestions all performed better than System.out.println. BufferedOutputStream seems to be the safest choice as it performed well in both test environments. BufferedWriter maybe faster though.

这些建议的表现都比 System.out.println 好。BufferedOutputStream 似乎是最安全的选择,因为它在两种测试环境中都表现良好。不过 BufferedWriter 可能更快。

Please post further suggestions if anyone has some ideas. I'm sure someone can make it go faster :)

如果有人有一些想法,请发表进一步的建议。我相信有人可以让它走得更快:)

回答by Mark Bramnik

Keep in mind that I/O operations are very slow compared to in-memory processing (e.g. parsing of Integer). So, I would propose you to create the whole string 'in advance' and then print it out only once (of course if its possible):

请记住,与内存中处理(例如解析整数)相比,I/O 操作非常慢。所以,我建议你“提前”创建整个字符串,然后只打印一次(当然如果可能的话):

StringBuilder sb = new StringBuilder();

StringBuilder sb = new StringBuilder();

for(int i = 0 ; i < 100000; i++) { sb.append(i).append("\n");}
String printMe = sb.toString(); 
System.out.println(printMe);

There are various techniques like buffering the the level of output stream you're using, but I assume that you prefer to stay with the most basic System.out.println

有多种技术,例如缓冲您正在使用的输出流的级别,但我假设您更喜欢使用最基本的 System.out.println

Hope this helps

希望这可以帮助

回答by Akash KC

For large amount of data,System.out.printlnmight be inefficient as it does not do very good buffering. In that case, you can use a BufferedOutputStreamor a BufferedWriter.

对于大量数据,System.out.println可能效率低下,因为它没有很好的缓冲。在这种情况下,您可以使用 aBufferedOutputStream或 a BufferedWriter

回答by Peter Lawrey

The slowest part of writing to System.out is the time taken to display what you are writing. i.e. for every line you write the computer has to turn the information into pixels using a font and scroll a whole line. This is much more work than whatever you are likely to be doing to display the text.

写入 System.out 最慢的部分是显示您正在编写的内容所花费的时间。即对于您编写的每一行,计算机必须使用字体将信息转换为像素并滚动整行。这比您可能为显示文本所做的工作要多得多。

You can speed up writing to the console by

您可以通过以下方式加快写入控制台的速度

  • writing less (usually the best idea)
  • writing to a file instead (This can be 5-10x faster)
  • 少写(通常是最好的主意)
  • 改为写入文件(这可以快 5-10 倍)

回答by Ujjwal Gautam

This includes fast input and output method as well

这也包括快速输入和输出方法

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();
      }
}