I have implemented a function that resets the content of the structure to which a pointer points:
template <typename Struct>
void initialize(Struct* s)
{
*s = Struct{};
}
I have performance issues when Struct
becomes big (above 10K) because Struct
is created in the stack and then assigned to *s
. I was wondering if I could improve it:
- Is it possible to initialize directly
*s
without the temporaryStruct{}
object? - Should I instead evaluate the size of
Struct
and build it in the heap if it is big?
Thank you in advance
Firstly, you should probably use a reference; not a pointer. The point of this is to avoid null indirection bugs.
If the class is trivial and value initialise to zero (which is typically the case for most trivial types), then the optimiser should compile your function into a call to
memset
, without any need for initialisation of a temporary object. So there should be no reason to worry in that case.You could call
memset
explicitly, although that is technically not portable to exotic systems in case the class contains certain types (for example, null pointer does not necessarily have the representation of zero).Yes, if you're willing to change the requirements of the function. Currently it works for classes that are default constructible and move assignable.
You can avoid creation of a temporary object if you modify the pointed object directly. In following example, there are no temporaries of type
Struct
created:To make this generic, the operation could be performed in a member function. Thus, you could specify a requirement that the pointed class has a member function with particular name and no parameters:
You can combine both approaches for types which they apply to:
If you need this to work with some classes that conforms to neither requirement, then you'll need to specialise the template.
You generally should avoid having public classes that large entirely. If you need such large storage, you could wrap it in a type that allocates it dynamically. Something like this: