home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 31,519 of 33,346   
   =?ISO-8859-1?Q?Daniel_Kr=FCgler?= to All   
   Re: what combination of type_traits to d   
   02 Oct 11 05:39:11   
   
   cdd70681   
   From: daniel.kruegler@googlemail.com   
      
   Am 01.10.2011 23:45, schrieb Ken:   
   > Hi,   
   >   
   > I need to allocate an array of 100mln small objects Foo dynamically at   
   > once.   
   >   
   > I have no issues telling std::vector how many I want, but I really   
   > don't want to call Foo() 100mln times (default constructor does   
   > nothing - would be fine if the objects were zero'ed out).   
      
   I have a problem with that description: What would be the difference between   
   zero-initialization and value-initialization for your type Foo?   
      
   Why do you resize or the resizing constructor at all? Better use reserve   
   (which does not do any memory initialization at all) and call push_back or   
   emplace_back (C++11) with the actually needed constructor?   
      
   > If Foo is a POD and I know that zero-initialization is ok, I can use   
   > calloc() to allocate my array and free() it later.  Unfortunately   
   > is_pod() is a little too restrictive - Foo is rather simple, but by   
   > just having any constructor, it is no longer POD (I need some non-   
   > default constructors for convenience).   
      
   You could use is_trivially_default_constructible from a C++11 compiler or - as   
   Dave suggested - has_trivial_default_constructor from boost.   
      
   > My question is, what combination of type_traits (including boost) can   
   > use use to write a template function:   
   >   
   > template<  typename T>   
   > bool IsSafeToCalloc() {   
   > // what conditions should I put here?  use some combination of   
   > type_traits?   
   > }   
   >   
   > Another interesting thing I found was that I wanted to elide the   
   > default destructor because it does nothing and I don't like ~Foo()   
   > being called 100mln times.  However, that effort failed too, as I need   
   > to use Foo as a value in a std::map and having value-semantics, gcc   
   > complains about not having a ~Foo().   
      
   Again, unclear: Does your type Foo has a trivial destructor or a non-trivial   
   destructor? If it is trivial I would expect that you couldn't observe a   
   difference when your type is element of std::vector.   
      
   > Bottom Line:  how do I inspect my class in order to avoid calling the   
   > constructor and destructor 200mln times in total?  BTW, I have   
   > profiled, and it's this chunk of allocation and deallocation that is   
   > taking far more time than anything else.   
      
   I would have been great, if you have provided a minimum Foo definition,   
   because that would resolve many open questions. I'm partially reading your   
   description in the way of "if have a non-trivial default constructor and a   
   non-trivial destructor in Foo,    
   but I don't want them to be called" which looks somehow odd to be. But even   
   oddness has a place in C++: You could store a proxy in std::vector and perform   
   two-phase construction, if you would prefer that.   
      
   > Aside: should I create a Foo_Core that has almost nothing (no   
   > constructors, destructors, etc...) to ensure that it's a POD and then   
   > a Foo class that operates on Foo_Core to provide class-like   
   > functionality?  almost seems like a functional-programming approach   
   > would work better here.   
      
   I don't think that you need POD-ness and I don't think you can enforce   
   POD-ness on Foo or a container of Foo. Sure, you could produce something like   
      
   struct Foo { ... };   
      
   struct Foo_Core { char foo[sizeof(Foo)]; };   
      
   and then use std::vector, but what would be the advantage? You would   
   still need to perform construction and destruction manually if either of these   
   would be non-trivial. I don't understand why your type Foo shouldn't be   
   effectively    
   administrated by std::vector. Maybe you are doing unnecessary operations? As   
   said earlier, you could first reserve the memory and than insert the wanted   
   elements into the container.   
      
   HTH & Greetings from Bremen,   
      
   Daniel Krügler   
      
      
      
   --   
         [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
         [ comp.lang.c++.moderated.    First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca