为什么System.out.println这么慢?

13 java performance

这是所有编程语言的共同点吗?进行多次打印然后使用println似乎更快但将所有内容移动到字符串并且只是打印似乎最快.为什么?

编辑:例如,Java可以在不到一秒的时间内找到所有素数高达100万 - 但是打印然后在他们自己的println上全部打印可能需要几分钟!打印高达100亿小时!

EX:

package sieveoferatosthenes;
public class Main {
    public static void main(String[] args) {
        int upTo = 10000000;
        boolean primes[] = new boolean[upTo];
        for( int b = 0; b < upTo; b++ ){
            primes[b] = true;
        }
        primes[0] = false;
        primes[1] = false;

        int testing = 1;

        while( testing <= Math.sqrt(upTo)){
            testing ++;
            int testingWith = testing;
            if( primes[testing] ){
                while( testingWith < upTo ){
                    testingWith = testingWith + testing;
                    if ( testingWith >= upTo){
                    }
                    else{
                        primes[testingWith] = false;
                    }

                }
            }
        }
        for( int b = 2; b < upTo; b++){
            if( primes[b] ){
                System.out.println( b );
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

And*_*s_D 25

println并不慢,它PrintStream是与托管操作系统提供的控制台连接的底层.

您可以自己检查:比较将大文本文件转储到控制台,并将相同的文本文件传输到另一个文件中:

cat largeTextFile.txt
cat largeTextFile.txt > temp.txt
Run Code Online (Sandbox Code Playgroud)

读取和写入类似于文件大小(O(n)),唯一的区别在于目标不同(控制台与文件相比).而且基本相同System.out.


底层操作系统操作(在控制台窗口上显示字符)很慢,因为

  1. 必须将字节发送到控制台应用程序(应该非常快)
  2. 每个char都必须使用(通常)一个真正的字体来渲染(这很慢,关闭抗锯齿可以提高性能,顺便说一句)
  3. 可能必须滚动显示的区域以便向可见区域附加新行(最佳情况:位块传输操作,最坏情况:重新呈现完整文本区域)


JBi*_*rch 5

System.out是一个静态PrintStream类.PrintStream除其他外,还有那些你可能非常熟悉的方法,比如print()等等println().

输入和输出操作需要很长时间才是Java的独特之处."长." 打印或写入只PrintStream需要几分之一秒,但是这种打印的超过100亿个实例可以相当多!

这就是为什么你的"将一切都移到一个字符串"是最快的.您构建了巨大的String,但只打印一次.当然,这是一个巨大的印刷品,但你花时间实际印刷,而不是与print()或相关的开销println().

正如Dvd Prd所提到的,字符串是不可改变的.这意味着无论何时将新String分配给旧String但重用引用,实际上都会销毁对旧String的引用并创建对新String的引用.因此,通过使用可变的StringBuilder类,您可以使整个操作更快.这将减少与构建您最终打印的字符串相关的开销.