一些人刚开始通过阅读 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 倍以上。太多了。我很困惑。想到了String对象的创建,GC,-server,yada,yada,yada。
当我发现几乎 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 启动时间)?