0

I've been running into a problem where calling std::vector.clear() on a large vector, n > 1,000,000 takes a many seconds.

It is currently std::vector of structs, which are basically POD. There is no clean up needed in the destructor. I've considered changing the structs to classes, because I wanted to add some functions to them, but I'm not sure how that will impact calling clear on vectors of large numbers of these classes/struct.

It boils down to wanting to know when std::vector.clear() will call a destructor. I was under the impression that these days there is no difference between a class and a struct in C++ other than struct members default to public.

I would hate to have to switch to using malloc, realloc and free myself and keeping track of the size just because I want to guarantee that destructors aren't being called, but it seems like I'm taking a performance hit even when calling clear().

bpeikes
  • 3,495
  • 9
  • 42
  • 80
  • What is "significant amount of time"? – andy256 Aug 14 '13 at 01:57
  • 3
    Did you supply a destructor for your struct? It's no longer a POD if you declared one. – greatwolf Aug 14 '13 at 01:59
  • 2
    *which are basically POD*. POD is a clear cut category, a type is either a POD or not a POD, it cannot be *basically* a POD. So what is it? --the answer to this is *very related* to your question. – David Rodríguez - dribeas Aug 14 '13 at 02:05
  • Are you sure that you are using POD? Check http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special for what makes a POD. – Chris Aug 14 '13 at 02:05
  • If this is related to your [previous question](http://stackoverflow.com/questions/18025031/how-would-you-manage-a-stdvector-of-structs-with-stdvectors-with-large-range) then your ORDER struct contains a `std::vector` and isn't POD. – Blastfurnace Aug 14 '13 at 02:59
  • I'm fairly sure it's a POD. I'll have to double check the code. There is definitely no user defined destructor, but I'll have to make sure that there are no members which have destructors. Will having a constructor which initializes members cause destructors to be called even if I don't have a user defined one? – bpeikes Aug 14 '13 at 03:02
  • If ORDER contains a `std::vector` as a non-static member then it is a non-POD struct. – Blastfurnace Aug 14 '13 at 03:11
  • Realistically, the dtor call will be inlined anyway. Even if it's formally non-trivial, the question still is whether the generated code is trivial. – MSalters Aug 14 '13 at 07:44
  • @Chris - I made some changes to the structures to actually separate the part of the structure which is a std::vector to attempt to avoid this problem. It seems to work, i.e. it cut a huge amount of time off the clear call, but it still seems to take longer than I would expect because I would think that if your have 1,000,000 POD structs in a vector, then clear would just set the size to 0, and leave the memory as is. I'm beginning to think it might be VS 2008 implementation of vector. – bpeikes Aug 15 '13 at 03:25

1 Answers1

3

Switching between struct and class won't make any difference -- you're correct that the only difference between them is default visible (public for structs, private for classes).

What matters is whether the items in the container have non-trivial destructors. If they're non-trivial, they'll be invoked. If they're trivial, there (at least generally) won't really be anything to invoke.

It's a little difficult to give decent advice about how to speed things up without any real idea about the current code and/or where the time it's taking is being consumed. In your position I'd be thinking hard about profiling the code. Once you know exactly where the time is being spent, you stand some chance of improving things -- but until then, you're pretty much shooting in the dark -- you might try to improve something that takes (nearly) no time to start with, so your improvement makes no difference, or you might work on something that matters, but end up making it slower instead of faster.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Indeed, for a class with a trivial destructor (which is one requirement for POD), its lifetime doesn't even end when you call `clear`. You are still allowed to access it until the underlying allocation block may be freed. But OP's note that "no clean-up needed in the destructor" seems to imply that there is a user-declared destructor, and they are not POD. – Potatoswatter Aug 14 '13 at 02:24
  • @Potatoswatter - There is no destructor, at least no user defined destructor. I'm going to double check that I didn't do something stupid like use a std::string as a member. – bpeikes Aug 14 '13 at 03:58