右辺値参照の代表的使い方である移譲処理でのパーフォーマンス効果

<実行環境>

Intel MacBook pro 16

 

<右辺値参照で移譲処理>

コピーは性能に大きな影響があるのは常ですが、じゃどれぐらい影響あるのか試してみました。

やってること、

① メモリ領域確保(初期化 or 未初期化:13行目の()有無)、この場合には100MB確保と領域の移譲処理

② 領域のコピー(有り or 無し:53/54/55行目のコメントアウト有無)

の4パターンの実行速度比較

#include <iostream>
#include <utility>

const long a_size = 1000000*100;

class home
{
    int* m_land;
    int* cp_land;

public:
    explicit home(long size)
        : m_land{new int[size] ()}{}
    
    ~home() { delete [] m_land;}

    home(home&& other);

    int* land() const { return m_land; }

    int* land_cp() const { return cp_land; }

    void copy()
    {
        cp_land = new int[a_size];
        for (int i = 0; i <= a_size; i++)
        {
            cp_land[i] = m_land[i];
        }
    }

    void del()
    {
        delete [] cp_land;
    }
};

home::home(home&& other)
    : m_land{other.m_land}
{
    other.m_land = nullptr;
}


int main()
{
    std::chrono::system_clock::time_point  start, end;
    start = std::chrono::system_clock::now();

    home A{a_size};
    std::cout << "A\'s land address : " << A.land() << std::endl;

    A.copy();
    std::cout << "A\'s cp_land address : " << A.land_cp() << std::endl;
    A.del();

    home B{std::move(A)};
    std::cout << "B\'s land address : " << B.land() << std::endl;

    std::cout << std::endl;
    end = std::chrono::system_clock::now();
    double elapsed = std::chrono::duration_cast(end-start).count();
    std::cout << "elapsed time : " << elapsed << " ms" << std::endl;
}

<結果>

・領域初期化有りモードではおおよそコピー時間差(領域初期化の有無で、領域コピー有りの時間にそれほど差はないのはなぜかと思うけど)、これを見ると領域の初期化も当然重い処理。

・領域初期化無では領域コピー実行の比重がほぼ100%、コピーしなければ1ms以下で処理完了してます。

・いずれにしろ、これらの処理が繰り返し実行される場合には大きなパーフォーマンスの差になるから、移譲は使える時には使ったほうが良い。

領域サイズ:100MB

<領域初期化有り>

・std::move
A's land address : 0x7ff049f00000
B's land address : 0x7ff049f00000

elapsed time : 166 ms

・+ 領域copy
A's land address : 0x7fb615700000
A's cp_land address : 0x7fb5f5700000
B's land address : 0x7fb615700000

elapsed time : 546 ms


<領域初期化無し>

・std::move
A's land address : 0x7fb23ff00000
B's land address : 0x7fb23ff00000

elapsed time : 0 ms

・+ 領域copy
A's land address : 0x7fb03df00000
A's cp_land address : 0x7fb01df00000
B's land address : 0x7fb03df00000

elapsed time : 514 ms

ソースは以下のリンクから、

https://github.com/chateight/c-plusplus/blob/master/move_perform.cpp

メモリ管理をマニュアルでやっていますが、vectorクラスのようなコンテナを使ったときのパーフォーマンスにも興味があります。

 

<疑問一点>

デストラクターでcp_landの解放すると、

*** error for object 0x7ff7b9aae490: pointer being freed was not allocated

のエラーが出ますが、なぜ?取り敢えずはdel()メソッド追加で対応してますが。

 

admin

 

カテゴリーc++