Archived

This topic is now archived and is closed to further replies.

_walrus

is this corrent and faster?

Recommended Posts

Hi i was just woindering if the two are equivalent and if the c version using ''memcpy'' and ''malloc'' is any faster than the ''new'' operator. Assume ''set'' assignes each value of the transformation individually with the ''='' operator. thanks Transform4 * Transform4::newCopy() { //faster than ''new'' and ''set()''? Transform4* copy = (Transform4*)malloc(sizeof(Transform4)); memcpy(copy, this, sizeof(Transform4)); return copy; } or is this faster? Transform4 * Transform4::newCopy() { Transform4* copy = new Transform4; copy -> setValues(this); return copy; }

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
why not just define a transform copy constructor?


  

class Transform
{
public:
Transform(const Transform& t)
: _x(t.x), _y(t._y) /// etc etc

{ }

Transform* newCopy();

private:
double _x;
double _y
/// etc, etc

};

Transform4 * Transform4::newCopy()
{
return new Transform4(*this);
}


My guess is that using copy constructor will be slightly faster than the C version, and certainly faster than the C++ version making setValue function call.

Share this post


Link to post
Share on other sites
Eventhough you can explicity use it the copy constructor still has to assign the 16 values explicty when using a copy constructor so i dont see how it is faster and. And you shouldn''t define a copy constructor unless you need to to deep copying. Since this class only holds 16 floats or doubles (and nothing that is dynamically created and needs to be explicity created when copying) the standard shallow copying will do (no need to override the copy constructor). Copy construtor is called when passing obects to functions or when a function is retuning an object an it is a copy that the fucntion gets (thus calling the copy costructor)


I guess what i''m asking above is is new followed by 16 assignments faster or is allocating a block of memory followed by one memcpy call faster? Will using malloc allow us to avoid calling the any constructor and will memcpy reduce 16 assignemnts to 1?

Share this post


Link to post
Share on other sites
You''ll find that the default copy constructor will be a memcpy, rather that the multiple assignments your suggesting. This is definately true when optimizations are turned on (and will probably be faster than anything you can come up with yourself), but I''m not 100% sure when optimizations are off....not that it matters since you''re after speed anyway.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:

I guess what i''m asking above is is new followed by 16 assignments faster or is allocating a block of memory followed by one memcpy call faster? Will using malloc allow us to avoid calling the any constructor and will memcpy reduce 16 assignemnts to 1?




  
A::A(const A& a)
{
f = a.f;
g = a.g;
// ...

}


is not the same as


  
A::A(const A& a) : f(a.f), g(a.g) /* ... */ {}

Share this post


Link to post
Share on other sites
quote:
Original post by joanusdmentia
You''ll find that the default copy constructor will be a memcpy, rather that the multiple assignments your suggesting. This is definately true when optimizations are turned on (and will probably be faster than anything you can come up with yourself), but I''m not 100% sure when optimizations are off....not that it matters since you''re after speed anyway.
If it did just a direct memcpy, none of the object members would get copied properly. They''d then contain pointers to internal data of some other object, reference counting wouldn''t work etc. Have you actually debugged the default copy constructor''s code?

Share this post


Link to post
Share on other sites
memcpy is a byte copier and you should write your own copier instead that handles the type of data you need to copy better. Copying by using DWORD is 4 times faster than the memcpy (provided that is the kind of data you want to copy) method.

straight from the source of memcpy:


  
void * __cdecl memcpy (
void * dst,
const void * src,
size_t count
)
{
void * ret = dst;

#if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) || defined (_M_IA64)
{
extern void RtlMoveMemory( void *, const void *, size_t count );

RtlMoveMemory( dst, src, count );
}
#else /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) || defined (_M_IA64) */
/*
* copy from lower addresses to higher addresses
*/
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
#endif /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) || defined (_M_IA64) */


return(ret);
}


I have seen better ways of copy data than that.

____________________________________________________________
Try RealityRift at www.planetrift.com

[edited by - MichaelT on January 18, 2003 6:04:46 AM]

Share this post


Link to post
Share on other sites
quote:

Original post by civguy
If it did just a direct memcpy, none of the object members would get copied properly. They'd then contain pointers to internal data of some other object, reference counting wouldn't work etc. Have you actually debugged the default copy constructor's code?



If your dealing with a transformation matrix with just 16 floats or doubles (which it's fairly safe to assume we are, since he does a memcpy himself) then what I said stands. Yes I've debugged default copy constructor code, but we aren't dealing with a complex class using inheretence or containing instances of other classes that themselves have non-default copy constructors.

In the context of the problem at hand, what I said was correct. I never mentioned anything about the general case. So please...stop talking out of your arse.


[edited by - joanusdmentia on January 18, 2003 7:07:47 PM]

Share this post


Link to post
Share on other sites