Reputation: 161
I am interested in the best way regarding performance of copying large containers. Imagine that one has a vector container that stores for example 60.000.000 entries (probably long doubles) or much more values. Now, if one is solving, for example, an ODE (ordinary differential equation), it is necessary (based on the algorithm in use) to make a copy of the old values which are used for the calculation to update the new values. Following (imaginary) example:
// 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
...
}
}
Sure, while taking the vector<long double> YprefIter
before the brackets, we do not have to create and destroy the object for each iteration. This should be definitely a better choice:
// 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;
...
}
}
However, I am asking myself, if there are more advanced solutions around. Such as using the move semantics
in such an example or do other things that I am not aware of stuff which would be much better in the sense of using actual developments. I would expect that my above-mentioned strategies are not state of the art. It just came into my mind that I could use two pointers while switching the pointing object for each iteration. However this is just a thought, did not test my logic here but the idea is that I do not need to copy anything; maybe a better solution and if such things work, I am sure there is already something implemented in 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
...
}
}
Any comment is appreciated. Tobi
Upvotes: 2
Views: 250
Reputation: 12749
The first snippet is basically something like this
for(i=0; i<iMax, ++i)
{
vector<long double> YprefIter = Y;
// ...
Y = f(YprefIter);
// ...
}
In this case, you could simply swap the two vectors:
// 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);
}
Upvotes: 3