-1

C++ で値渡しと参照渡しの速度をテストしたい:

class MyAddress{
    char *name;
    long int number;
    char *street;
    char *town;
    char state[2];
    long zip;
    std::vector<int> v_int;
public:
    MyAddress(int i){
        v_int.resize(1000000);
        std::fill(v_int.begin(),v_int.end(),i);
    }
    MyAddress& assign1(MyAddress const& x)
    { 
        MyAddress tmp(x);       // copy construction of tmp does the hard work
        std::swap(*this, tmp);  // trade our resources for tmp's
        return *this;           // our (old) resources get destroyed with tmp 
    }
    MyAddress& assign2(MyAddress x)//x is a copy of the source 
    {                              //hard work already done

        std::swap(*this, x);  // trade our resources for x's
        return *this;         // our (old) resources get destroyed with x 
    }
    void f1(MyAddress v){int i=v.v_int[3];}
    void f2(MyAddress const &ref){int i=ref.v_int[3];}

};

MyAddress get_names(MyAddress& ref){return ref;}

主要:

int _tmain(int argc, _TCHAR* argv[])
{
    float time_elapsed1=0;
    float time_elapsed2=0;

    for(int i=0;i<100;i++){
        {
            MyAddress a1(1);
            MyAddress a2(2);
            MyAddress a3(3);
            clock_t tstart=std::clock();
            a1.f1(a2);
            a1.f1(a3);
            clock_t tend=std::clock();
            time_elapsed1+=((float)tend-(float)tstart);
        }
        {
            MyAddress a1(1);
            MyAddress a2(2);
            MyAddress a3(3);
            clock_t tstart=std::clock();
            a1.f2(a2);
            a1.f2(a3);
            clock_t tend=std::clock();
            time_elapsed2+=((float)tend-(float)tstart);
        }
    }
    std::cout<<std::fixed<<"\nassign1 time elapsed : "
         <<time_elapsed1/CLOCKS_PER_SEC;
    std::cout<<std::fixed<<"\nassign2 time elapsed : "
         <<time_elapsed2/CLOCKS_PER_SEC;
    system("pause");
    return 0;
}

時差の結果は衝撃的です。

assign1 経過時間: 81.044998

assign2 経過時間: 0.002000

これは正しいです?

「値による」速度が「参照による」速度よりもはるかに速いのはなぜですか?

4

2 に答える 2

1

出力の文言には混乱があります。コードのどこにもassign1andを使用していませんが、出力で言及しています。assign2

とにかく、あなたが実際に何をしているかを見た後、私が言えることf1は、引数をで受け取ることです。つまり、コピー コンストラクターを呼び出します。これは、大きすぎるメンバー ベクトルをコピーします。f2このベクトルのコピーにはそれだけの時間がかかりますが、参照によって引数を取るため、呼び出すときに節約できます。そのため、この場合、ベクトルのコピーは作成されません。

于 2012-05-20T17:18:35.277 に答える
0

高価なコピー コンストラクターについて既に述べたことに加えて、 と の計算結果を破棄しているだけであることを述べておきたいと思いf1ますf2。つまり、理論的には (これが可能になるようにベクトルが実装されている場合)、値が読み取られるだけの場合、コンパイラはメソッド呼び出し全体を削除することを決定でき、値を削除しても副作用が発生しないことは明らかです。つまり、タイマー自体の開始と停止にかかる時間だけを測定することになる可能性があります。

とにかく、少なくとも大きなオブジェクトを渡す場合は、いくつかのケースを除いて、参照による呼び出しの方が高速であると期待する必要があります。

于 2012-05-20T17:34:44.450 に答える