簡體   English   中英

在 C++ 中復制大容器的最佳方法

[英]Best way for copying large container in c++

我對復制大型容器的最佳性能感興趣。 想象一下,一個向量容器存儲了例如 60.000.000 個條目(可能是長雙精度)或更多的值。 現在,如果有人正在求解,例如,一個 ODE(常微分方程),則有必要(基於所使用的算法)復制用於計算的舊值以更新新值。 以下(假想)示例:

// This container is inside a class (so it is initialized and stored at the memory during runtime)
vector<long double> Y(60000000,0);

// Later on in a function
void solve()
{
    for(i=0; i<iMax, ++i)
    {
        // Make a copy for the field one is solving for (depending on the algorithm in use if it is needed)
        // The following is not the best solution as we allocate and deallocate YprefIter for each
        // Iteration; imagine iMax = 1000000
        vector<long double> YprefIter = Y;
        ...

        // Do some analysis (simplified); 
        Y = something * YprefIter * something + anything

        // As YprefIter might be used somewhere else, we cannot update Y only
        Y = YprefIter + Y * whatever
        ...
    }
}

當然,在括號之前使用vector<long double> YprefIter ,我們不必為每次迭代創建和銷毀對象。 這絕對是一個更好的選擇:

// This container is inside a class (so it is initialized and kept)
vector<long double> Y(60000000,0);

// Later on in a function
void solve()
{
    vector<long double> YprefIter (Y.size(), 0);

    for(i=0; i<iMax, ++i)
    {
        // Make a copy for the iteration algorithm
        // Better solution as we get rid of the memory allocation and deallocation 
        YprefIter = Y;
        ...
    }
}

但是,我在問自己,是否有更高級的解決方案。 例如在這樣的例子中使用move semantics或做其他我不知道的事情,在使用實際開發的意義上會更好。 我希望我的上述策略不是最先進的。 我突然想到我可以在為每次迭代切換指向對象時使用兩個指針。 然而這只是一個想法,沒有在這里測試我的邏輯,但我的想法是我不需要復制任何東西; 也許是一個更好的解決方案,如果這樣的事情有效,我相信已經在 C++ 中實現了一些東西:)

// This container is inside a class (so it is initialized and kept)
vector<long double> Y(60000000,0);

// Later on in a function
void solve()
{
    // Create the second object
    vector<long double> YprefIter (Y.size(), 0);

    // Pointer 1 and Pointer 2
    vector<long double>* pToY = NULL;
    vector<long double>* pToYPref = NULL

    // Set pointer pToY to point to Y
    pToY = &Y;

    for(i=0; i<iMax, ++i)
    {
        // Switch the Pointer fields for each iteration
        if (i%2)
        {
            pToY = &Y;
            pToYPrefIter = &YPrefIter;
        }
        else
        {
            pToY = &YPrefIter;
            pToYPrefIter = &Y;
        }

        // Work with the pointers afterwards
        ...
    }
}

任何評論表示贊賞。 托比

第一個片段基本上是這樣的

for(i=0; i<iMax, ++i)
{
    vector<long double> YprefIter = Y;
    //  ...
    Y = f(YprefIter);
    //  ...
}

在這種情況下,您可以簡單地交換兩個向量:

// Initialize Y_old
vector<long double> Y_old = whatever(),
                    Y;
for(i=0; i<iMax, ++i)
{
    //  ...
    Y = f(Y_old);
    //  ...
    // The swap is implemented in terms of moves, it doesn't copy the values.
    std::swap(Y_old, Y);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM