考虑以下两个代码段:
System.out.print(i + " ");
或
System.out.print(i);
System.out.print(" ");
虽然两者最终都会打印相同的输出,但在执行速度方面,哪种变体会更快?
在某些情况下,我要问的原因是,将第一个转换为第二个会在我的联机编译器中导致“超过时间限制(tle)”错误。这表明第一种方法速度更快,但我不知道这是否普遍适用。我也想知道为什么。
考虑以下两个代码段:
System.out.print(i + " ");
或
System.out.print(i);
System.out.print(" ");
虽然两者最终都会打印相同的输出,但在执行速度方面,哪种变体会更快?
在某些情况下,我要问的原因是,将第一个转换为第二个会在我的联机编译器中导致“超过时间限制(tle)”错误。这表明第一种方法速度更快,但我不知道这是否普遍适用。我也想知道为什么。
1条答案
按热度按时间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 + " "
会更快。