有一些新手通过阅读K&R来学习C语言,并在第一页上印出了它的华氏温度转摄氏温度的循环:
#include <stdio.h>
main ()
{
int fahr;
for (fahr = 0; fahr<= 200000000; fahr = fahr + 20)
printf("%d\t%6.2f\n", fahr, (5.0 / 9.0) * (fahr-32));
}
他被告知Java很慢。因此,告诉他现在Java非常有竞争力,但在这种简单情况下C可能会更快。想要证明给他看并将"System.out."添加到printf()前面。结果比之前慢了10倍以上,太慢了,让人惊讶。考虑到字符串对象的创建、垃圾收集、-server等问题。当我发现实际上几乎100%的时间都花费在printf() (
PrintSteam.write()
, 输出通过/ dev / null管道)时,我更加困惑了。经过一些尝试,我得出了以下结论(目前不进行%f的舍入):public static void main(String... args) throws Exception {
int fahr=0;
PrintWriter out = new PrintWriter(Channels.newWriter(Channels.newChannel(System.out), "US-ASCII") );
int max = 2000000000;
for (fahr = 0; fahr<= max; fahr = fahr + 20)
// out.printf("%d\t%6.2f\n", fahr, (5.0 / 9.0) * (fahr-32));
out.println( fahr + "\t" + f(((5.0 / 9.0) * (fahr-32)) ));
out.close();
}
private static final String f(double d) {
return (int)d + "." + (int)((d - (int)d)*100);
}
}
所以,这里使用了 NIO 技术。经过测试,在两台机器上的表现都超过了gcc -O2。
问题:
- 为什么将 C 语言文本字面直译成 Java (例如
PrintStream
)如此缓慢? - (为什么注释掉的
out.printf()
如此缓慢 [也许随着时间的推移性能会下降]?) - 最后:为什么我的解决方案比 C 语言更快(包括 JVM 的启动时间)?