java—在调用print()或多次调用print()时串联字符串是否更快?

rekjcdws  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(404)

考虑以下两个代码段:

System.out.print(i + " ");

System.out.print(i);
System.out.print(" ");

虽然两者最终都会打印相同的输出,但在执行速度方面,哪种变体会更快?
在某些情况下,我要问的原因是,将第一个转换为第二个会在我的联机编译器中导致“超过时间限制(tle)”错误。这表明第一种方法速度更快,但我不知道这是否普遍适用。我也想知道为什么。

yruzcnhs

yruzcnhs1#

你不可能真正知道-这取决于代码中不明显的因素。

我什么时候慢一点?

为了让它慢一点, i 必须是非常大的字符串(或 toString() 方法返回一个非常大的字符串,从而导致 i + " " 操作相对昂贵。它仍然是一个完全在内存中的事务,因此与大多数i/o相比,它可以忽略不计,但是如果将它设为一个大约一百万个字符的字符串,那么很可能会导致速度变慢。

我是什么时候,然后慢一点? System.in 是否缓冲。你得不到任何保证。它通常是一个相当大的系统链连接在一起,最终,您将写入一个文件(如果您运行 java -cp . yourpkg.YourClass >output.txt 例如)或控制台,如果该控制台通过ssh、网络上的tcp/ip数据包等运行。

许多这样的系统增加了大量的开销,因为它们是所谓的“打包”系统:它们根本不能发送或处理单个字节。它们只能处理相当大的块。以网络为例:要将一些数据从互联网上的一台计算机发送到另一台计算机,就要将要发送的数据打包成一个所谓的数据包,其中包含许多字节的数据,用于处理这些数据的系统,以便知道如何处理这些数据。这些数据将通过你的网卡,你的路由器,街道尽头的小衣柜,你镇上更大的网络中心,到一个主要的传输干线,穿过光纤到大洋彼岸,然后所有这些,回到你所拥有的服务器 ssh -他突然陷入困境。应该很明显,你需要相当多的信息字节来实现这一点。
所以,如果你想 Hello 再也没有什么了,就形成了一个完整的包。它本可以携带1800字节的数据,但只能携带5字节。它仍然有~100字节的路由信息开销。所以,hello数据包总共大约有105个字节大。你的网卡把它转移到你的路由器上,然后它就转移到广阔的世界上,然后你的代码几乎马上就会说:好的,太好了,现在发送一个空间这会导致你的系统尽职尽责地制作另一个包,应用所有的路由开销,然后关闭一个101字节的包,总共2个单独的包,总共206字节。
对比发送 Hello 一次,一个106字节的数据包。
这就是为什么通常的“缓冲”,或者失败的话,将发送集中到更少的实际写入中,速度会更快的一个例子。但问题是,你不知道在哪里 System.out 去吧。慰问?网络?文件?比特桶?谁知道呢。如果你跑了 java -jar yourapp.jar >/dev/null , System.out 速度非常快(因为数据毫无进展)。你的问题没有提到这件事的进展。
注:文件最终也是基于数据包的,现代固态硬盘不能将单个字节写入磁盘,只能一次性写入整个数据块。如果您首先写入“hello”,ssd会将整个数据块读取到内存中,然后更新一些字节以便它们读取“hello”,然后用重置整个数据段的电源脉冲刷新磁盘上的位置,然后将数千字节的整个数据块写回。如果你再写一个空间,那么整个例程将被第二次执行,而如果你只调用一次write,那么磁盘很可能只执行一次“加载整个区块、更新数据、缓冲区块、保存区块”的歌舞例程。

好吧,你能简化一下吗?

哦,不。这就是重点。然而,通常情况下,这并不重要,而且它们同样快。但是,如果有关系的话,很可能 i + " " 会更快。

相关问题