在调用print()或多次调用print()中连接字符串是否更快?
考虑以下两个代码片段:
System.out.print(i + " ");
或者
System.out.print(i);
System.out.print(" ");
尽管两者最终都会打印相同的输出,但就执行速度而言,哪个变体会更快?
在某些情况下,我问的原因是将第一个转换为第二个会导致我的在线编译器出现“超出时间限制 (TLE)”错误。这表明第一个更快,但我不知道这是否普遍正确。我也想明白为什么。
回答
您无法真正知道 - 这取决于您的代码中不明显的因素。
什么时候比较i + " "慢?
为了更慢,i需要一个非常大的字符串(或者一些对象的toString()方法返回一个非常大的字符串,从而导致i + " "操作相对昂贵。它仍然完全是内存中的事情,所以与大多数I/O相比,它可以忽略不计,但是将其设为一百万个字符左右的字符串,这可能会导致速度变慢。
什么时候i,然后" "更慢?
System.in是,或不是,缓冲。你得不到任何保证。它通常是连接在一起的相当大的系统链,最终,您最终会写入文件(java -cp . yourpkg.YourClass >output.txt例如,如果您运行)或控制台,如果该控制台通过 ssh、TCP/IP 数据包通过网络运行,等等.
许多这些系统增加了大量的开销,因为它们是所谓的“打包”系统:它们根本无法发送或处理单个字节。它们只能处理相当大的块。以网络为例:要将一些数据从 Internet 上的一台计算机发送到另一台计算机,您需要将要发送的数据包装在一个所谓的数据包中,该数据包包括许多字节的数据,用于处理该数据的系统以了解要发送的内容用它。这些数据将通过您的网卡、路由器、街道尽头的小柜子、城镇中较大的网络集线器,到达主要的分配干线,通过光纤到达大洋彼岸,以及然后所有这些,回到你已经ssh进入的服务器。应该很明显,您需要相当多的信息字节才能实现这一点。
所以,如果你只想发送Hello而已,那么就制作一个完整的数据包。它可能承载了 1800 字节的数据,但它只能承载 5 个。它仍然有大约 100 字节的路由信息开销。因此,Hello 数据包总共大约有 105 个字节。你的网卡将它分流到你的路由器,然后它被传送到广阔的世界,然后你的代码几乎立即说:好的,太好了,现在发送一个空间!- 这导致您的系统尽职尽责地制作另一个数据包,应用所有路由开销,然后关闭一个 101 字节的数据包,总共 2 个单独的数据包,总计 206 字节。
与Hello 一次性发送相比,对于 106 字节的单个数据包。
这就是为什么通常“缓冲”或失败的一个例子,将您的发送集中到更少的实际写入中,会更快。但问题是,你不知道System.out去哪里。安慰?网络?文件?比特桶?谁知道。如果您运行java -jar yourapp.jar >/dev/null,System.out速度非常快(因为数据绝对无处可去)。你的问题没有提到这去哪里了。
注意:文件最终也是基于数据包的,现代 SSD 不能将单个字节写入磁盘,只能一次性写入整个块。如果您首先写入“hello”,则 SSD 最终会将整个块读入内存,然后更新一些字节以便它们读取“hello”,然后用大量电源刷新磁盘上的位置以重置整个段,然后写入整个大块的数千字节大回。如果你然后写一个空间,整个例程会第二次完成,而如果你只调用一次 write,磁盘可能会这样做“加载整个块,更新数据,冲击块,保存块”歌曲和舞蹈例行公事只有一次。
好的,你能简化一下吗?
嗯,不。这才是重点。但是,通常,这无关紧要,它们同样快。但是,如果这很重要,那很可能i + " "会更快。