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 について考えました。
PrintSteam.write()
実際にはほぼ 100% の時間が printf() (出力は /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 を使用します。また、テストした 2 台のマシンで gcc -O2 よりも優れています。
質問:
- C から Java へのリテラル トランススクリプト (つまり
PrintStream
)が非常に遅いのはなぜですか? - (コメント
out.printf()
が遅いのはなぜですか [時間の経過とともにパフォーマンスが低下する可能性があります]?) - 最後に: なぜ私のソリューションは C よりも高速なのですか (JVM の起動時間を含む)?