Why is System.out.println so slow?

后端 未结 7 1215
情歌与酒
情歌与酒 2020-11-27 08:30

Is this something common to all programming languages? Doing multiple print followed by a println seems faster but moving everything to a string and just printing that seem

7条回答
  •  有刺的猬
    2020-11-27 08:52

    The problem you have is that displaying to the screen is very espensive, especially if you have a graphical windows/X-windows environment (rather than a pure text terminal) Just to render one digit in a font is far more expensive than the calculations you are doing. When you send data to the screen faster than it can display it, it buffered the data and quickly blocks. Even writing to a file is significant compare to the calculations, but its 10x - 100x faster than displaying on the screen.

    BTW: math.sqrt() is very expensive, and using a loop is much slower than using modulus i.e. % to determine if a number is a multiple. BitSet can be 8x more efficient than boolean[]

    If I dump the output to a file, it is quick, but writing to the console is slow, and if I write to the console the data which was written to a file it takes about the same amount of time.

    Took 289 ms to examine 10,000,000 numbers.
    Took 149 ms to toString primes up to 10,000,000.
    Took 306 ms to write to a file primes up to 10,000,000.
    Took 61,082 ms to write to a System.out primes up to 10,000,000.
    
    time cat primes.txt
    
    real    1m24.916s
    user    0m3.619s
    sys     0m12.058s
    

    The code

    int upTo = 10*1000*1000;
    long start = System.nanoTime();
    BitSet nonprimes = new BitSet(upTo);
    for (int t = 2; t * t < upTo; t++) {
        if (nonprimes.get(t)) continue;
        for (int i = 2 * t; i <= upTo; i += t)
            nonprimes.set(i);
    }
    PrintWriter report = new PrintWriter("report.txt");
    long time = System.nanoTime() - start;
    report.printf("Took %,d ms to examine %,d numbers.%n", time / 1000 / 1000, upTo);
    
    long start2 = System.nanoTime();
    for (int i = 2; i < upTo; i++) {
        if (!nonprimes.get(i))
            Integer.toString(i);
    }
    long time2 = System.nanoTime() - start2;
    report.printf("Took %,d ms to toString primes up to %,d.%n", time2 / 1000 / 1000, upTo);
    
    long start3 = System.nanoTime();
    PrintWriter pw = new PrintWriter(new BufferedOutputStream(new FileOutputStream("primes.txt"), 64*1024));
    for (int i = 2; i < upTo; i++) {
        if (!nonprimes.get(i))
            pw.println(i);
    }
    pw.close();
    long time3 = System.nanoTime() - start3;
    report.printf("Took %,d ms to write to a file primes up to %,d.%n", time3 / 1000 / 1000, upTo);
    
    long start4 = System.nanoTime();
    for (int i = 2; i < upTo; i++) {
        if (!nonprimes.get(i))
            System.out.println(i);
    }
    long time4 = System.nanoTime() - start4;
    report.printf("Took %,d ms to write to a System.out primes up to %,d.%n", time4 / 1000 / 1000, upTo);
    report.close();
    

提交回复
热议问题