JavaとC#でチェックとアンチェックの整数オーバーフローの時間差を測定しようとしています。C#とJavaのオーバーフローチェックが狂ったパフォーマンス偏差
私は、チェックされたJavaコードがC#に比べて高速かつ高速になることに気付きました。何故ですか?
C#コードとJavaチェックコードの間に大きな違いがあるのはなぜですか?C#コードとJavaチェックなしコードの両方がほぼ同じように機能するのはなぜですか?
C#コード:
class Program
{
static void Checked()
{
Random random = new Random();
Stopwatch time = new Stopwatch();
time.Start();
int rez = 0;
for (int i = 0; i < 500000; i++)
{
int a = random.Next(Int32.MaxValue); // edit
int b = random.Next(Int32.MaxValue); // edit
try
{
checked
{
rez = a + b;
// rez = random.Next(Int32.MaxValue) + random.Next(Int32.MaxValue); // edit
}
}
catch { }
}
time.Stop();
Console.WriteLine(rez);
Console.WriteLine("Checked: " + time.ElapsedMilliseconds + "ms");
}
static void Unchecked()
{
Random random = new Random();
Stopwatch time = new Stopwatch();
time.Start();
for (int i = 0; i < 500000; i++)
{
int rez = random.Next(Int32.MaxValue) + random.Next(Int32.MaxValue);
}
time.Stop();
Console.WriteLine("Unchecked: " + time.ElapsedMilliseconds + "ms");
}
static void Main(string[] args)
{
for(int i = 0; i < 10; i++)
{
Checked();
Unchecked();
Console.WriteLine();
}
}
}
Javaコード:
public class CheckedUnchecked {
public static void checked() {
Random random = new Random();
long start = System.nanoTime();
int rez = 0;
for (int i = 0; i < 500000; i++) {
try {
rez = Math.addExact(random.nextInt(Integer.MAX_VALUE), random.nextInt(Integer.MAX_VALUE));
}catch(Exception e) {}
}
System.out.println(rez); // prevent jvm from optimizing variable out, ignore in final output
long time = System.nanoTime() - start;
System.out.printf("checked %.1f ms%n", time/1e6);
}
public static void unchecked() {
Random random = new Random();
long start = System.nanoTime();
int rez = 0;
for (int i = 0; i < 500000; i++) {
rez = random.nextInt(Integer.MAX_VALUE) + random.nextInt(Integer.MAX_VALUE);
}
System.out.println(rez);
long time = System.nanoTime() - start;
System.out.printf("unchecked %.1f ms%n", time/1e6);
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
checked();
unchecked();
System.out.println();
}
}
}
C番号:チェック
:7846ms 未チェック:チェック17ms
:7806ms 未確認:17ms
チェック:7788ms未確認 :チェック17ms
:7798ms未確認 :チェック17ms
:7739ms未確認 :チェック17ms
:7907ms未確認 :17ms
チェック:7840ms 未チェック:17ms
チェック:7805msチェックなし :チェック17ms
:7836msチェックなし :チェック17ms
:7771ms チェックなし:17ms
Javaは:
は693.7ミリ 未確認23.6ミリ
をチェックしますチェック済み799.9 ms 未チェック14.9 ms
は 未確認13.8ミリ
は482.8ミリ 未確認14.1ミリ
が 未確認13.7ミリ
が 未確認13.7ミリ
は490.1ミリを確認487.0ミリを確認483.4ミリを確認確認488.1ミリを確認しました 未チェック14.1 ms
チェック済み499.9 ms 未チェック13.8 ms
チェック済み485.9 ms 未チェック13。 CPU:インテルCore i3-2100 3.10GHz のWindows 10 64ビット
Javaバージョン "1.8.0_121"
@ 9ミリは481.2ミリ 未確認13.8ミリ
システム情報をチェックします
Java(TM)SE Runtime Environment(ビルド1.8.0_121-b13)
Java HotSpot(TM)64ビットサーバーVM(ビルド25.121-b13、混合モード
VS2015 Community Editionリリース構成に付属のC#デフォルトコンパイラ
チェックされたブロックの前に2つの乱数を作成し、チェックされたブロックに追加するだけです。 –
@ k5_しました。さらに遅くても8000ms前後になります。私は引数が常に範囲内にあることを知っているので、random.Nextも例外をスローすることができたので、tryブロックからもそれを移動させることができます。 – stigma6
ベンチマーク時に出力ラインを含めないでください。特にプラットフォームの1つではありません。 –