Java System.out.print 效率

标签 java performance io stringbuilder

在过去的几天里,做了一些竞争性的编程练习,我发现了一些问题的解决方案,而不是在 for 中在控制台中打印出文本。循环,他们构建了一个 StringBuilder通过将文本相互附加。一开始我很困惑,但我尝试了一下并做了一些基准测试。

第一次测试:这是在屏幕上打印内容的经典方法:

class TestClass {

    public static void main(String args[]) throws Exception {
        double startTime = System.currentTimeMillis();

        //code
        for (int i = 0; i < 1000000; i++) {
            System.out.print("test");
        }
        //code
        double endTime = System.currentTimeMillis();
        String result = String.format("for loop: %.5f", (endTime-startTime) / 1000);
        System.out.print("\n"+result);
    }

}

第二次测试:这是增强版,StringBuilder :

class TestClass {

    public static void main(String args[]) throws Exception {
        double startTime = System.currentTimeMillis();

        //code
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 1000000; i++) {
            sb.append("test");
        }
        System.out.print(sb);
        //code
        double endTime = System.currentTimeMillis();
        String result = String.format("for loop: %.5f", (endTime - startTime) / 1000);
        System.out.print("\n" + result);
    }

}

经过多次测试(使用Intel i5 6500四核3.2 GHZ CPU,Win 10运行),结果如下:

first test(for loop): 4,25s  
second test(StringBuilder): 0.23s

结果并不意外,因为 out.print是同步的,所以每次我们调用它时,都会增加一些开销。但慢了近 20 倍有点奇怪。

我的问题是:我们有办法进一步改进吗?

最佳答案

在这种情况下,不应归咎于

synchronized 关键字。

第一个测试用例很慢,因为System.out.print会带来频繁的最小I/O。

你可以使用BufferedWriter(它的write方法也是同步的)来减少不必要的I/O:

BufferedWriter log = new BufferedWriter(new OutputStreamWriter(System.out));

//code
for (int i = 0; i < 1000000; i++) {
    log.write("test");
}

for loop: 0.21200
<小时/>

并且,StringBuilder在内部使用byte[]进行字符存储。当您通过将旧值复制到新的 byte[] 中不断追加内容时,该字节数组将会增长。

给它足够大的容量可能会带来一些效率:

StringBuilder sb = new StringBuilder(1000000 * 10);

关于Java System.out.print 效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51990047/

相关文章:

c - 哪个更快更好?这种比较方法是真的吗?

html - 清理 angularjs Controller 和功能 - 用于具有多选定制的下拉列表

c - 用 C 语言逐行读取文件

java - 使用属性文件中的位置读取文件

python - 何时在 Python 中使用 io.BytesIO() 修改字符串

java - 查找树是否平衡的迭代解决方案

Java 执行带参数的 C 应用程序并取回返回值?

Windows x64 上的 Python x64 位复制文件性能评估/问题

java - 一个 classe owl api 的父类(super class)

java - 尝试运行一个带有按钮的简单应用程序