3 つの主要な言語間で生の CPU パフォーマンス速度を比較してきました (コードと結果は以下にあります)。主な言語が生の計算能力をどのように比較するかについて、私は非常に興味があります。Java と C# は、メモリのオーバーヘッドがなければ C++ に匹敵する可能性があるという理論がありました。
私の質問:
1) 編集済み (C++ のタイミングがより現実的になりました)
2) JVM は最初の反復で時間がかかりましたが、2 番目の反復では分析が終了して最適化されたと考えるのは正しいですか? Hotspot は、外側のループの最初の繰り返しの後、途中ではなく最適化を終了することをどのように認識したのでしょうか?
3) C# が Java のように機能せず、最初から大幅に最適化されないのはなぜですか? Java に関して C# の違いは何ですか? C# が遅いのはなぜですか? 単純に最適化が少ないためですか?
4) C# テストのタイミングで 2246 ミリ秒と 2262 ミリ秒の間で変動する特定の理由はありますか? CPU には 2 つのコアがあるため、これは 2 つの異なる時間である可能性がありますか?
編集: C# コードでストップウォッチの使用法を表示するようにコードを更新しています。
編集: C++ タイミング コードと結果を修正
セットアップ:
C++: VS2010 および Intel Compiler (組み込みリリース モード、最適化: O2、組み込み関数を有効にする: はい、サイズまたは速度を優先する: どちらでもない、フレーム ポインターを省略する: いいえ、ファイバーセーフ最適化を有効にする: いいえ、プログラム全体の最適化: はい)
Java: Eclipse、Hotspot 64 ビット コンパイラ バージョン 17、Java 1.6
C#: VS2010 および .net 4.0 (ビルトイン リリース モード)
CPU: Intel E6600 (2.4GHz) 2.7GHz で動作、バス速度 300MHz、メモリ 8GB、DRAM 周波数: 375MHz
- 勝つ 7 (64 ビット)
C++ コード:
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <mmsystem.h>
#include <stdio.h>
#include <fstream>
using namespace std;
double PCFreq = 0.0;
__int64 CounterStart = 0;
void StartCounter()
{
LARGE_INTEGER li;
if(!QueryPerformanceFrequency(&li))
cout << "QueryPerformanceFrequency failed!\n";
PCFreq = li.QuadPart;
QueryPerformanceCounter(&li);
CounterStart = li.QuadPart;
}
double GetCounter()
{
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
return double(li.QuadPart-CounterStart)/PCFreq;
}
static long counter = 0;
int _tmain(int argc, _TCHAR* argv[])
{
for (int m = 0; m < 10; m++)
{
StartCounter();
counter = 0;
for (int j = 0; j < 3; j++)
{
//Just to test timing is working correctly
//int* p = new int;
for (long i = 0; i < 200000000; i++)
{
counter++;
}
}
cout << GetCounter()*1000000 << " microseconds" << endl;
}
int p = 0;
cin >> p;
return 0;
}
C++ の結果:
7.19 マイクロ秒
1.89
2.27
1.51
4.92
10.22
10.22
9.84
9.84
10.6
Java コード:
public class main {
static long counter = 0;
public static void main(String[] args) {
for(int m=0; m<10; m++){
long start = System.nanoTime();
counter = 0;
for(int j=0;j<3; j++){
for(long i=0; i<200000000; i++){
counter++;
}
}
System.out.println(((System.nanoTime()-start)/1000000) + " ms");
}
}
}
Java の結果:
5703 milliseconds
471 ms
468 ms
467 ms
469 ms
467 ms
467 ms
467 ms
469 ms
464 ms
C# コード:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics
namespace t1
{
class Program
{
static long counter = 0;
static void Main(string[] args)
{
for (int m = 0; m < 10; m++)
{
Stopwatch s = new Stopwatch();
s.Start();
counter = 0;
for (int j = 0; j < 3; j++)
{
for (long i = 0; i < 200000000; i++)
{
counter++;
}
}
s.Stop();
Console.WriteLine(s.Elapsed.TotalMilliseconds + " ms");
}
Console.ReadLine();
}
}
}
C# の結果:
2277 ミリ秒
2246ミリ秒
2262ミリ秒
2246ミリ秒
2262ミリ秒
2246ミリ秒
2262ミリ秒
2246ミリ秒
2262ミリ秒
2262ミリ秒