【问题标题】:What's the fastest way to output a string to system out?将字符串输出到系统的最快方法是什么?
【发布时间】:2012-08-06 05:50:51
【问题描述】:

我正在做这样的事情:

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

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

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

【问题讨论】:

  • 尝试几种方法并分析它们。

标签: java


【解决方案1】:

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

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 可能更快。

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

【讨论】:

【解决方案2】:

对于大量数据,System.out.println 可能效率低,因为它不会 做很好的缓冲。在这种情况下,您可以使用BufferedOutputStreamBufferedWriter

【讨论】:

    【解决方案3】:

    请记住,与内存中的处理相比,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

    希望对你有帮助

    【讨论】:

    • 或者使用 BufferedWriter 也能达到同样的效果。
    • 感谢您的建议,我将创建一个测试程序来比较它们。
    • 我认为您的意思是 Integer.toString(int) 而不是使用 Integer.parseInt(String)
    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

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

      您可以通过

      加快写入控制台的速度
      • 少写(通常是最好的主意)
      • 改为写入文件(这可能快 5-10 倍)

      【讨论】:

      • 或写入一个空设备(例如/dev/null),这会切断存储层。
      猜你喜欢
      • 2010-12-06
      • 1970-01-01
      • 2021-06-09
      • 1970-01-01
      • 2010-10-19
      • 2014-03-19
      • 1970-01-01
      • 1970-01-01
      • 2013-03-03
      相关资源
      最近更新 更多