runtime performance impact of template usage

A

Aaron Anodide

Hello,

I am using the following template class as a shorthand for zero-ing memory:

template<class T>
class ZeroMem : public T
{
public:

ZeroMem(void)
{
ZeroMemory( this, sizeof(T) );
}
};

Then, I do things like:

ZeroMem<MYSTRUCT> mystruct;

My question is: Does using this have any runtime performance impact? My
hope is that the inline constructor causes this usage of this template to be
eqiv to a macro.

Thanks,
Aaron Anodide
 
J

John Harrison

Aaron Anodide said:
Hello,

I am using the following template class as a shorthand for zero-ing memory:

template<class T>
class ZeroMem : public T
{
public:

ZeroMem(void)
{
ZeroMemory( this, sizeof(T) );
}
};

Then, I do things like:

ZeroMem<MYSTRUCT> mystruct;

My question is: Does using this have any runtime performance impact? My
hope is that the inline constructor causes this usage of this template to be
eqiv to a macro.

Thanks,
Aaron Anodide

The *only* way to find out would be to look at the machine code generated by
your compiler. C++ does not require inline funcitons to be actually inlined,
its only a hint.

In any case the overhead for a function call is nano-seconds, are you
claiming that this would make a noticeable difference to your program? Have
you timed anything? Unless the answer to both those questions is yes, you
should be concentrating on writing clear code, not tricks with templates.

I think your method is somewhat dubious because you are creating different
types from what you really want. Isn't a template function better

template <class T>
void ZeroMem(T& obj)
{
ZeroMemory(&obj, sizeof(T));
}

MYSTRUCT mystruct;
ZeroMem(mystruct);

john
 
A

Aaron Anodide

John Harrison said:
to

The *only* way to find out would be to look at the machine code generated by
your compiler. C++ does not require inline funcitons to be actually inlined,
its only a hint.

In any case the overhead for a function call is nano-seconds, are you
claiming that this would make a noticeable difference to your program? Have
you timed anything? Unless the answer to both those questions is yes, you
should be concentrating on writing clear code, not tricks with templates.

I think your method is somewhat dubious because you are creating different
types from what you really want. Isn't a template function better

template <class T>
void ZeroMem(T& obj)
{
ZeroMemory(&obj, sizeof(T));
}

MYSTRUCT mystruct;
ZeroMem(mystruct);

Thanks for the tip. This is a good idea.

Sincerely,
Aaron Anodide
 
J

John Carson

Aaron Anodide said:
Hello,

I am using the following template class as a shorthand for zero-ing
memory:

template<class T>
class ZeroMem : public T
{
public:

ZeroMem(void)
{
ZeroMemory( this, sizeof(T) );
}
};

Then, I do things like:

ZeroMem<MYSTRUCT> mystruct;

My question is: Does using this have any runtime performance impact?
My hope is that the inline constructor causes this usage of this
template to be eqiv to a macro.

Thanks,
Aaron Anodide

I think that it is rather neat the way you derive from a template parameter
but, on a more practical level, what's wrong with

MYSTRUCT mystruct = {0};

?
 
A

Aaron Anodide

John Carson said:
I think that it is rather neat the way you derive from a template
parameter

slightly OT, but ATL does this all over the place. I didn't think it up.
but, on a more practical level, what's wrong with

MYSTRUCT mystruct = {0};

Honestly, I wasn't aware of that. I've seen reams of example code using
ZeroMemory on windows or memset(). I've never seen ={0}; Is this standard
c++?

Thanks,
Aaron
 
J

John Carson

Aaron Anodide said:
slightly OT, but ATL does this all over the place. I didn't think it
up.


Honestly, I wasn't aware of that. I've seen reams of example code
using ZeroMemory on windows or memset(). I've never seen ={0}; Is
this standard c++?

Thanks,
Aaron


Yes, it is standard. It can't be used for dynamically allocated memory, but
it works for all other memory allocation. It is just a special case of the
rules for struct initialisation. Given a plain struct (no constructor etc.)
like

struct S
{
int x,
char *str,
int y;
};

You can initialise it with, say,

S s = {5, "Name", 9};

The rules say that if you only partially initialise the struct, e.g.,

S s = {5};

then everything in the remainder of the struct is initialised to zero, i.e.,
the preceding line is equivalent to

S s = {5, 0, 0};

Thus if you enter

S s = {0};

then this is equivalent to

S s = {0, 0, 0};
 
A

Aaron Anodide

John Carson said:
Yes, it is standard. It can't be used for dynamically allocated memory, but
it works for all other memory allocation. It is just a special case of the
rules for struct initialisation. Given a plain struct (no constructor etc.)
like

struct S
{
int x,
char *str,
int y;
};

You can initialise it with, say,

S s = {5, "Name", 9};

The rules say that if you only partially initialise the struct, e.g.,

S s = {5};

then everything in the remainder of the struct is initialised to zero, i.e.,
the preceding line is equivalent to

S s = {5, 0, 0};

Thus if you enter

S s = {0};

then this is equivalent to

S s = {0, 0, 0};

Thanks for the info. I wonder why so many people use memset or ZeroMemory
on stack variable structs then?

What about nested structs?

struct S
{
int x;
};
struct T
{
int y;
S s;
};

will your initialization scheme work here too?

Aaron
 
J

John Carson

Aaron Anodide said:
Thanks for the info. I wonder why so many people use memset or
ZeroMemory on stack variable structs then?


The ={0} approach is a technique inherited from C. People brought up on
constructors may not be familiar with it or may not have bothered to
remember it. Stroustrup discusses it in TC++PL.

What about nested structs?

struct S
{
int x;
};
struct T
{
int y;
S s;
};

will your initialization scheme work here too?

Aaron


Yes. Just to make it slightly more interesting, suppose we have:

struct S
{
int w, x;
};

struct T
{
int y;
S s;
};

You could explicitly initialise this with:

T t = {3, {5, 7}};

The nested brackets, however, only make the code visually clearer. The
following is equivalent:

T t = {3, 5, 7};

The same rules apply. If you only partially initialise, then everything not
explicitly initialised is set to zero. Thus

T t = {3};

sets the nested S structure to zero, while

T t = {0};

sets everything to zero.
 
A

Aaron Anodide

John Carson said:
The ={0} approach is a technique inherited from C. People brought up on
constructors may not be familiar with it or may not have bothered to
remember it. Stroustrup discusses it in TC++PL.

Thanks again for the background info. It's very interesting to learn
something I did not know previously.

As a footnote, I wonder if the guys writing the Unit test cases for my C++
compiler forgot about the ={0} as well.....

Aaron
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top