add a smart realloc algorithm when filling a sparse matrix

This commit is contained in:
Gael Guennebaud 2009-01-18 18:00:19 +00:00
parent 0c7974dd4d
commit d58bb54e7f
3 changed files with 20 additions and 8 deletions

View File

@ -82,7 +82,7 @@ class CompressedStorage
reallocate(m_size); reallocate(m_size);
} }
void resize(int size, int reserveSizeFactor = 0) void resize(int size, float reserveSizeFactor = 0)
{ {
if (m_allocatedSize<size) if (m_allocatedSize<size)
reallocate(size + reserveSizeFactor*size); reallocate(size + reserveSizeFactor*size);
@ -98,6 +98,7 @@ class CompressedStorage
} }
int size() const { return m_size; } int size() const { return m_size; }
int allocatedSize() const { return m_allocatedSize; }
void clear() { m_size = 0; } void clear() { m_size = 0; }
Scalar& value(int i) { return m_values[i]; } Scalar& value(int i) { return m_values[i]; }

View File

@ -200,7 +200,21 @@ class SparseMatrix
int startId = m_outerIndex[outer]; int startId = m_outerIndex[outer];
int id = m_outerIndex[outer+1]-1; int id = m_outerIndex[outer+1]-1;
++m_outerIndex[outer+1]; ++m_outerIndex[outer+1];
m_data.resize(id+2);
float reallocRatio = 1;
if (m_data.allocatedSize()<id+2)
{
// we need to reallocate the data, to reduce multiple reallocations
// we use a smart resize algorithm based on the current filling ratio
// we use float to avoid overflows
float nnzEstimate = float(m_outerIndex[outer])*float(m_outerSize)/float(outer);
reallocRatio = (nnzEstimate-float(m_data.size()))/float(m_data.size());
// let's bounds the realloc ratio to
// 1) reduce multiple minor realloc when the matrix is almost filled
// 2) avoid to allocate too much memory when the matrix is almost empty
reallocRatio = std::min(std::max(reallocRatio,1.5f),8.f);
}
m_data.resize(id+2,reallocRatio);
while ( (id >= startId) && (m_data.index(id) > inner) ) while ( (id >= startId) && (m_data.index(id) > inner) )
{ {
@ -209,10 +223,7 @@ class SparseMatrix
--id; --id;
} }
m_data.index(id+1) = inner; m_data.index(id+1) = inner;
//return (m_data.value(id+1) = 0); return (m_data.value(id+1) = 0);
m_data.value(id+1) = 0;
// std::cerr << m_outerIndex[outer] << " " << m_outerIndex[outer+1] << "\n";
return m_data.value(id+1);
} }
// inline void // inline void

View File

@ -151,7 +151,7 @@ class SparseVector
{ {
int startId = 0; int startId = 0;
int id = m_data.size() - 1; int id = m_data.size() - 1;
m_data.resize(id+2); m_data.resize(id+2,1);
while ( (id >= startId) && (m_data.index(id) > i) ) while ( (id >= startId) && (m_data.index(id) > i) )
{ {
@ -172,7 +172,7 @@ class SparseVector
void resizeNonZeros(int size) { m_data.resize(size); } void resizeNonZeros(int size) { m_data.resize(size); }
inline SparseVector() : m_size(0) { resize(0, 0); } inline SparseVector() : m_size(0) { resize(0); }
inline SparseVector(int size) : m_size(0) { resize(size); } inline SparseVector(int size) : m_size(0) { resize(size); }