java - StringBuffer 与普通打印

标签 java stringbuffer

与将所有数组项附加到 StringBuffer 然后打印相比,为什么在循环中打印数组项需要更多时间?

在此,我在循环中打印了数组项。

public static void main (String[] args) {
    Scanner scan=new Scanner(System.in);
    int count=scan.nextInt();
    for (int i=0;i<count;i++) {
        int arrlen=scan.nextInt();
        int rotate=scan.nextInt();
        int revarr[]=new int[arrlen];
        for (int j=0;j<arrlen;j++) {
            revarr[(arrlen-rotate+j)%arrlen]=scan.nextInt();
        }
        for (int j:revarr) {
            System.out.print(j+" ");
        }   
        System.out.println();
    }
}

在此,我将数组项附加到 StringBuffer 中,然后打印。

public static void main (String[] args) {
    Scanner scan=new Scanner(System.in);
    int count=scan.nextInt();
    for (int i=0;i<count;i++) {
        int arrlen=scan.nextInt();
        int rotate=scan.nextInt();
        int revarr[]=new int[arrlen];
        for(int j=0;j<arrlen;j++){
            revarr[(arrlen-rotate+j)%arrlen]=scan.nextInt();
        }
        StringBuffer s = new StringBuffer();
        for (int j:revarr){
            s.append(j+" ");
        }   
        System.out.println(s);
    }
}

最佳答案

可能的原因与 System.out 设置为(默认情况下)的 PrintStream 的实现有关。

在Java 11中,创建PrintStream的方法如下:

private static PrintStream newPrintStream(FileOutputStream fos, String enc) {
   if (enc != null) {
        try {
            return new PrintStream(new BufferedOutputStream(fos, 128), true, enc);
        } catch (UnsupportedEncodingException uee) {}
    }
    return new PrintStream(new BufferedOutputStream(fos, 128), true);
}

关键行是这样的:

return new PrintStream(new BufferedOutputStream(fos, 128), true, enc);

首先,它创建一个缓冲区大小为 128 字节的 BufferedOutputStream。那很小。如果您对 System.out 进行少量写入,则每写入 128 个字节至少就会发生一次缓冲区刷新。

其次,true 参数启用自动刷新。 javadoc对此进行了如下描述:

"If true, the output buffer will be flushed whenever a byte array is written, one of the println methods is invoked, or a newline character or byte ('\n') is written"

同样,这意味着有更多的潮红。

为什么这会产生影响?

井刷新涉及执行fwrite系统调用来写出字符。系统调用相对昂贵。根据我看到的一些数字,fwrite 系统调用的系统调用开销约为 60 到 350 ns。这并不是很大,但如果您在每个循环迭代中执行几次与每个循环迭代一次相比,并且您重复该操作足够长的时间,则差异可能会很大。

还可能存在一些开销,具体取决于 System.out 连接的内容。例如,如果您正在写入控制台,则大量小写入可能会减慢控制台应用程序的速度。

<小时/>

还有另一种解释是可能的。您所显示的基准测试代码没有考虑任何可能的 JVM 预热影响。例如,可能一个示例正在触发 JIT 编译,而另一个示例则没有。 JIT 编译的开销可能会导致前者比后者花费更长的时间。

关于java - StringBuffer 与普通打印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61318082/

相关文章:

java - 反序列化字符串缓冲区

java - Java 中的 Vigenere/多字母密码解码器/解密器/解密器

java - OpenJPA 将另一表中的数据插入到一个表中

java - 将 Python 2D ndarray 加载到 Android 以在 TFLite 上进行推理

java - 替换两个位置之间的字符串中的特定字符

java - 使用StringBuffer删除重复项的方法

java - android中创建后的文件在哪里?

java - java中一个类的对象在2个不同的JVM上的序列化

java - java中可变字符串和不可变字符串有什么区别

java - 如何使用 stringbuilder 保存已删除的字符