-1

C++ に 1 つのコード、C# に 1 つのコードがあります。

1 つの .push-back と 1 つの .add の周りの時間を測定したことを強調しておきます。10000 回の発生について、費やした時間を書きます。したがって、コードの残りの部分は重要ではありません。説明のために書いただけです。

C++ コード

void pv(int depth, m1* prevM1)
{
    if (depth == 0)
        return;
    vector <m1> *mList;
    if (prevM1->childM1 != 0)
        mList = prevMove->childM1;
    else 
    {
        mList = new vector<m1>;   
        f1 (mList);
    }
    for(vector<m1>::iterator it=mList.begin(); it !=m1.end(); ++it)
    {
         pv(depth - 1 ,it.chilM1);
    }
    prevM1->childM1 = mList;
}



void f1(vector<m1>* Moves)
{

//私はカウンターとこのpush_backの周りの時間を持っています. 10000回に達したら時間を印刷します

    m1 obj;
    Moves->push_back(obj);

// そしてここ

    m1 obj2;
    Moves->push_back(obj2);
    m1 obj3;
    Moves->push_back(obj3);
    m1 obj4;
    Moves->push_back(obj4);
    m1 obj5;
    Moves->push_back(obj5);
    m1 obj6;
    Moves->push_back(obj6);
    m1 obj7;
    Moves->push_back(obj7);
    m1 obj8;
    Moves->push_back(obj8);
    m1 obj9;
    Moves->push_back(obj9);
    m1 obj10;
    Moves->push_back(obj10);
}

--------> これをメインで実行します

m1 move;
PV(10, &Moves);

C# コード

m1 f1()
{
    List<m1> Moves = new List<m1>();

//私はこのAddの周りにカウンターと時間を持っています. 10000回に達したら時間を印刷します

    m1 obj = new m1();
    Moves.Add(obj);

//そしてここ

    m1 obj2 = new m1();
    Moves.Add(obj2);        
    m1 obj3 = new m1();
    Moves.Add(obj3);        
    m1 obj4 = new m1();
    Moves.Add(obj4);        
    m1 obj5 = new m1();
    Moves.Add(obj5);        
    m1 obj6 = new m1();
    Moves.Add(obj6);        
    m1 obj7 = new m1();
    Moves.Add(obj7);        
    m1 obj8 = new m1();
    Moves.Add(obj8);        
    m1 obj9 = new m1();
    Moves.Add(obj9);        
    m1 obj10 = new m1();
    Moves.Add(obj10);
    return Moves;    
}

void PV(int depth,m1 prevM1)
{
    List<m1> mList;
    if (depth == 0)
    {
        return;
    }
    if (prevMove.childM1 != null)
    {
        mList = prevMove.childM1;
    }
    else
    {
        mList = f1();
    }
    foreach(m1 move in mList)
    {
        pv(depth - 1, move);
    }

--------> これをメインで実行します

m1 move;
PV(10, move); 

m1 クラスは、C# の c++ と c# の両方で同じです

class m1
{
    public String ms;
    public List<m1> childM1;
    public double d;
}

C++で

class m1
{
    public:
        string ms;
        m1* childM1;
        double d;
}

c# のコードは 12 ミリ秒で実行されましたが、c++ のコードは 143 ミリ秒で実行されました。違いを確認するために、何度も実行します。c++ のコードは、c# のコードよりも少なくとも 10 倍遅くなりました。c++ の vector は c# の List と同じなので、何かを見逃しているように見えるので、この違いを見つけました。

どんな助けでも大歓迎です。

4

3 に答える 3

4

最大の違いは、C++ コードがvector各ループ反復の後にローカルを破棄し、によって割り当てられたメモリを解放することpush_backです。C# コードは local への参照を放棄するだけListで、ガベージ コレクターがそれを処理します。これにより、ループが高速化される可能性がありますが、プログラムによって実行される作業の合計量はおそらく非常に似ています。

おそらく他にも多くの違いがあります。異なるパフォーマンス特性を持つ 2 つの異なる言語を比較しています。

于 2012-08-27T10:37:57.800 に答える
3

C++ は値ベースです。つまり、m1オブジェクトのコピーを作成します。C# は参照ベースです。つまり、オブジェクトへの参照を保存します。

そうは言っても、作成したパフォーマンス テストは実際には何も測定していないと思います。どちらのコンパイラも、ループ内で実際には何も行われていないことを検出し、最適化して取り除くことができると想像できます。より合理的なテストは、参照によって渡されたコンテナーに要素を追加することです (C# は既定でポインターを渡します)。

于 2012-08-27T10:35:48.733 に答える
1

'同等の'コードにはいくつかの問題があります。

1)C ++はvector、ブロックの最後での割り当てを解除する必要があります。C#はローリングを続けることができ、プログラムの存続期間の終わりにオブジェクトとリストを削除します

2)C ++文字列とC#文字列は完全に異なるものです。C ++では、std::string任意の長さのstingを格納でき、メモリの割り当て/割り当て解除を行う必要があるcharの配列です。C#stringは、最も可能性の高いポインターnullです。

于 2012-08-27T10:44:50.813 に答える