Fastest way of freeing up a vector

Started by
8 comments, last by Oxyacetylene 18 years, 7 months ago
I have 4 vector arrays of pointers to objects in a class, when the destructor to the class is called the elements are deleted and the vector is cleared, this is fine but it can take 10-15 seconds to remove everything, what is the quickest way to free all memory the pointers point to? This is what i have at the moment:

	~OBJObject()
	{
		for (vector<OBJFace*>::iterator i = pFaces.begin(); i != pFaces.end(); i++)
			delete *i;
		for (vector<CVec3*>::iterator i = pVertices.begin(); i != pVertices.end(); i++)
			delete *i;
		for (vector<CVec2*>::iterator i = pTexCoords.begin(); i != pTexCoords.end(); i++)
			delete *i;
		for (vector<CVec3*>::iterator i = pNormals.begin(); i != pNormals.end(); i++)
			delete *i;

		pFaces.clear();
		pVertices.clear();
		pTexCoords.clear();
		pNormals.clear();
	}

Is there a faster way???
Member of the NeHe team.
Advertisement
Quote:Original post by Kazade
Is there a faster way???



As something as low level as 2/3-vector storing pointers to them in a dynamic array is basically committing suicide unless you have a very, very good reason. For these kind of low-level types store the actual type and not a pointer to it, when std::vector is destroyed it will deallocate a chunk of memory all in one go and not per-element like you are doing. if you need to incrementally initialize/add elements and you know (roughly) how many elements you need in advance use std::vector::reserve and then std::vector::push_back.
look into pooling memory clicky
For future reference, if you're storing pointers to objects allocated on the heap in a vector, and you want them to be deleted when you erase the vector, then store a vector full of smart pointers, such as boost::shared_ptr. Then the memory will be automatically reclaimed when the vector is erased. This is safer, because you can't forget to delete anything.

This would mean your destructor code could be replaced by this.

~OBJObject(){                pFaces.clear();		pVertices.clear();		pTexCoords.clear();		pNormals.clear();}


This should be lot faster, because in your code you're iterating through each array, deleting each member, whereas this version just calls clear, and lets the destructor of boost::shared_ptr do the work of deleting the items in the array.
Quote:Original post by petewood
look into pooling


I.

typedef std::vector<CVec3, boost::pool_allocator<CVec3> > pool_vec3_vec;
Quote:Original post by Oxyacetylene
This would mean your destructor code could be replaced by this.

No destructor needed. You wouldn't need to call clear on the vectors since they clear themselves when destroyed.
Quote:Original post by SiCrane
Quote:Original post by Oxyacetylene
This would mean your destructor code could be replaced by this.

No destructor needed. You wouldn't need to call clear on the vectors since they clear themselves when destroyed.


D'oh, I should have remembered that, especially considering it's one of the reasons I use std::vector over dynamic arrays. *slaps head*
Quote:Original post by SiCrane
Quote:Original post by Oxyacetylene
This would mean your destructor code could be replaced by this.

No destructor needed. You wouldn't need to call clear on the vectors since they clear themselves when destroyed.


I was just about to say [grin], and i don't think it will be any faster (at least nothing significantly noticeable) infact its most likely to be slightly slower (with a slight alteration to the original code) hence the existance of Boost Pointer Container Library.

I still stand by what i said earlier, having something like a vertex buffer using an array of pointers to 2/3-vector is silly, i'll just quote myself:

Quote:Original post by snk_kid
typedef std::vector<CVec3, boost::pool_allocator<CVec3> > pool_vec3_vec;
However, smart pointers would probably be even slower as they have to perform refernce counting AND still have to call delete on every object.

The speed problem here is almost certainly related to freeing a large amount of small heap-allocated memory.

There are 2 approaches to solving this that I can see:

1:
Use vector::reserve to pre-allocate the memory and hold the objects by value

2:
Use a pool allocator and hold objects by value again


EDIT:
I wouldn't be in the least bit suprised if simply switching from pointers to objects gave you a dramatic speed increase, even without reserve or a custom allocator.
Yeah, I'm beginning to see my comment about shared_ptr being a faster solution was a bit uninformed, so I take it back.

My original thinking was that I thought it'd probably be faster to call delete[] once for each array, (which I assume is what vector::clear does? Although assumptions are a bad thing.) rather than calling delete once for each member of the array, but I wasn't thinking about the fact that the destructor of shared_ptr is essentially doing the same thing. I also wasn't thinking about the overhead of reference counting.

I wasn't disagreeing that switching from pointers to objects was a good idea though, I just wanted to say that using shared_ptr is a better solution when you have to store objects on the heap. (even though it's not actually faster)

Just wanted to clear that up, since there's nothing worse than someone saying something uninformed, and then failing to admit that they were wrong later on.

This topic is closed to new replies.

Advertisement