|
From: Alfred P. R. <al...@ya...> - 2005-04-20 17:47:06
|
Hi Francesco, Your array of class objects would be better served if it where a list or vector of class objects instead of an array. Then you can use the iterator features, including list and vector specific swap and sort member functions. If you must use an array of class objects, then there's always the <algorithm> standard template library header. Algorithm has a rich set of functions that include swap, sort, and other useful data manipulation algorithms such as unique, etc. These functions are usually optimized, and work in most instances significantly better than manually coded swap or sort functions. I'm not actually sure what you mean by "deep copy", however, I'm assuming that you mean actual data copying. You shouldn't be copying data to swap it! You should be swapping pointers to the data. Maybe the issue is in using a class class_objects[array_size]; declaration vs. a class *class_objects; declaration, because the overloaded operator= may operate in a different fashion between a pointer and an array element (i.e. class_objects[7], is a pointer, but in machine code is actually a set of pointer arithmetic operations). The class operator= should already be configured to correctly do something like: class *obj_a, *obj_b, *temp; obj_a = new class; ...; temp = obj_a; obj_a = obj_b; obj_b = temp; delete(temp); ... so that should work correctly, ***** however ***** list<class> obj_list; list<class>::iterator obj_iter; obj_list.push_back(obj_a); ... obj_iter = obj_list.begin(); obj_list.sort() or obj_list.sort( compare_function ); ... is easier, more elegant, and uses the optimized features of C++! Hopefully the above helps! Francesco <xtr...@vi...> wrote: Hi everybody, I'm a total beginner and I have the following problem: I have an array of objects instantiated from a class that has member pointers to dynamically allocated data. This class has also the usual overloaded operator=. I have to sort this array and I need to do some swapping. But swapping by "deep copy" seems useless to me in this case, thus is it possible somehow to override the overloaded operator= and use just for the swapping the normal operator =? I could use memcpy for a bitwise copy, but it seems to be significantly slower, especially for small objects. Thanks in advance, Francesco <snip> Alfred P. Reaud |
|
From: <Mat...@Ve...> - 2005-04-21 17:03:43
|
Alright. Once you have overloaded an operator, you are stuck with that
operator. However, overloaded operators apply on a class by class basis. The
HugeStuff type will not use the operator= that you defined for your class.
Can you think of a way to refactor your operator= to operate in terms of the
default operator= define for type HugeStuff?
Also, memcpy should be very fast. If it's not, try rolling your own. It
might work something like the below code. Also make sure you enable -O3
-fexpensive-optimizations when you build the code. You might also need -mcpu
and -mtune.
Some routines benefit heavily from optimization. Copy-heavy routines seem to
need help with this. When I wrote a crypto algorithm a while ago, it doubled
the speed to optimize it fully.
void copy(void* begin, void* end, void* dest)
{
for((char*) i=0; i<(char*)end; i++)
{
*(char*)dest=(char*)(begin+i);
}
}
HTH!
Matt
-----Original Message-----
From: dev...@li...
[mailto:dev...@li...]On Behalf Of Francesco
Sent: Thursday, April 21, 2005 3:02 AM
To: Alfred P. Reaud
Cc: Dev C++
Subject: Re: [Dev-C++] Shallow copy
Thanks for answering Alfred,
I'm already using the STL but since I'm still in a learning stage I was
trying to understand the "inner workings". Suppose I'm building ( just for
my own pleasure :-) ) a simple competitor to the vector template. Or to make
it even more banal, suppose I have the following code:
class MyData
{
typeHugeStuff * mHugeStuffPtr;
// ....
public:
// ....
MyData const & operator=( MyData const & inMyData ); // the
definition of this copies also the stuff pointed to by mHugeStuffPtr
// .....
};
template< typename T >
void MySwap( T * inDataPtr1, T * inDataPtr2 )
{
#ifdef BAD_SWAP
// the following will swap in memory the two objects but will also
deallocate/allocate/copy hugeStuff
T tempData;
tempData = *inDataPtr1;
*inDataPtr1 = *inDataPtr2;
*inDataPtr2 = tempData;
#else
// the following will just swap bitwise the members of the two
objects without erasing/duplicating/whatever hugeStuff
// but this bitwise copy seems to be slower than using the operator=
(when it's not overloaded)
// so I was wondering if it is possible to access the UNoverloaded
operator= in objects that have overloaded it....
char * aPtr;
aPtr = (char*) malloc ( sizeof( T ) );
memcpy( aPtr, inDataPtr1, sizeof( T ) );
memcpy( inDataPtr1, inDataPtr2, sizeof( T ) );
memcpy( inDataPtr2, aPtr, sizeof( T ) );
free( aPtr );
#endif
}
void main( void )
{
MyData * aDataPtr;
aDataPtr = new MyData[ 100 ];
FillUp( aDataPtr, 100 ); // filling up with data
MySwap< MyData >( aDataPtr + 20, aDataPtr + 40 ); // just
because.... :-)
}
Thanks in advance for any insight,
Francesco
On Apr 20, 2005, at 7:46 PM, Alfred P. Reaud wrote:
Hi Francesco,
Your array of class objects would be better served if it where a list or
vector of class objects instead of an array. Then you can use the iterator
features, including list and vector specific swap and sort member functions.
I f you must use an array of class objects, then there's always the
<algorithm> standard template library header. Algorithm has a rich set of
functions that include swap, sort, and other useful data manipulation
algorithms such as unique, etc. These functions are usually optimized, and
work in most instances significantly better than manually coded swap or sort
functions.
I'm not actually sure what you mean by "deep copy", however, I'm assuming
that you mean actual data copying. You shouldn't be copying data to swap
it! You should be swapping pointers to the data. Maybe the issue is in
using a class class_objects[array_size]; declaration vs. a class
*class_objects; declaration, because the overloaded operator= may operate in
a different fashion between a pointer and an array element (i.e.
class_objects[7], is a pointer, but in machine code is actually a set of
pointer arithmetic operations). The class operator= should already be
configured to correctly do something like:
class *obj_a, *obj_b, *temp;
obj_a = new class; ...;
temp = obj_a; obj_a = obj_b; obj_b = temp;
delete(temp); ...
so that should work correctly, ***** however *****
list<class> obj_list;
list<class>::iterator obj_iter;
obj_list.push_back(obj_a); ...
obj_iter = obj_list.begin();
obj_list.sort() or obj_list.sort( compare_function );
...
is easier, more elegant, and uses the optimized features of C++! Hopefully
the above helps!
Francesco <xtr...@vi...> wrote:
Hi everybody,
I'm a total beginner and I have the following problem:
I have an array of objects instantiated from a class that has member
pointers to dynamically allocated data. This class has also the usual
overloaded operator=. I have to sort this array and I need to do some
swapping. But swapping by "deep copy" seems useless to me in this case,
thus is it possible somehow to override the overloaded operator= and
use just for the swapping the normal operator =? I could use memcpy for
a bitwise copy, but it seems to be significantly slower, especially
for small objects.
Thanks in advance,
Francesco
<snip>
Alfred P. Reaud
<image.tiff>
___________________________________________________________________
The information contained in this message and any attachment may be
proprietary, confidential, and privileged or subject to the work
product doctrine and thus protected from disclosure. If the reader
of this message is not the intended recipient, or an employee or
agent responsible for delivering this message to the intended
recipient, you are hereby notified that any dissemination,
distribution or copying of this communication is strictly prohibited.
If you have received this communication in error, please notify me
immediately by replying to this message and deleting it and all
copies and backups thereof. Thank you.
|
|
From: Per W. <pw...@ia...> - 2005-04-21 18:01:19
|
For small objects, an inlined copy function might be better, but for
larger blocks, the memcpy() function is optimized to switch over to 32-bit
(or larger) moves for maximum performance, i.e. it definitely wins over a
char* copy.
By the way, a couple of problems with the code:
No (char*)i - you wan't to declare i as a variable, not typecast it to
char*.
Second, avoid extra variables. Your code is using 4 variables. Instead of
creating a new variable i and do begin+i you should increment begin.
Besides using a variable less, it also optimizes the memory reference for
some processors.
A low-end memcpy() looks something like:
void* copy(void *dst,void *src,unsigned size) {
char* orig_dst = dst;
char* end = (char*)src + size;
while ((char*)src < end) {
*((char*)dst)++ = *((char*)src)++;
}
return orig_dst;
}
A normal memcpy() will do some optional single byte copies at start to get
word-aligned, and then do several unrolled word-copies (as large word as
possible, i.e. normally 32 or 64 bit) and then end with some optional
single-byte copies again.
If data is known to always be well-aligned and of a reasonable size, a
better code would be (pseudo-code):
void* copy(void *dst,void *src,unsigned size) {
// Observe: Code assumes that src and dst are aligned to sizeof(long)
// If they are not, one or more single-byte copy are needed...
void* orig_dst = dst;
unsigned r = size % sizeof(unsigned long);
unsigned count = size / sizeof(unsigned long);
if (size >= 4) {
// Unroll loop 4 times.
size >>= 2;
r += 4*sizeof(unsigned long);
} else {
// Too small block to unroll.
r += 4*size;
size = 0;
}
for (;size; size--) {
*((unsigned long*)dst)++ = *((unsigned long*)src)++;
*((unsigned long*)dst)++ = *((unsigned long*)src)++;
*((unsigned long*)dst)++ = *((unsigned long*)src)++;
*((unsigned long*)dst)++ = *((unsigned long*)src)++;
}
// r and this code not needed if size is a multiple of sizeof(long)
for (;r; r--) {
*((char*)dst)++ = *((char*)src)++;
}
return *orig_dst;
}
In reality, this kind of code is written in assembler, to allow further
optimizations by for example using calculated jumps into the unrolling
code. Also, some processors have special instructions for memory transfer
operations.
/Per W
On Thu, 21 Apr 2005 Mat...@Ve... wrote:
> Alright. Once you have overloaded an operator, you are stuck with that
> operator. However, overloaded operators apply on a class by class basis. The
> HugeStuff type will not use the operator= that you defined for your class.
> Can you think of a way to refactor your operator= to operate in terms of the
> default operator= define for type HugeStuff?
>
> Also, memcpy should be very fast. If it's not, try rolling your own. It
> might work something like the below code. Also make sure you enable -O3
> -fexpensive-optimizations when you build the code. You might also need -mcpu
> and -mtune.
>
> Some routines benefit heavily from optimization. Copy-heavy routines seem to
> need help with this. When I wrote a crypto algorithm a while ago, it doubled
> the speed to optimize it fully.
>
> void copy(void* begin, void* end, void* dest)
> {
> for((char*) i=0; i<(char*)end; i++)
> {
> *(char*)dest=(char*)(begin+i);
> }
> }
>
> HTH!
> Matt
> -----Original Message-----
> From: dev...@li...
> [mailto:dev...@li...]On Behalf Of Francesco
> Sent: Thursday, April 21, 2005 3:02 AM
> To: Alfred P. Reaud
> Cc: Dev C++
> Subject: Re: [Dev-C++] Shallow copy
>
>
> Thanks for answering Alfred,
> I'm already using the STL but since I'm still in a learning stage I was
> trying to understand the "inner workings". Suppose I'm building ( just for
> my own pleasure :-) ) a simple competitor to the vector template. Or to make
> it even more banal, suppose I have the following code:
>
>
> class MyData
> {
> typeHugeStuff * mHugeStuffPtr;
> // ....
> public:
> // ....
> MyData const & operator=( MyData const & inMyData ); // the
> definition of this copies also the stuff pointed to by mHugeStuffPtr
> // .....
> };
>
>
> template< typename T >
> void MySwap( T * inDataPtr1, T * inDataPtr2 )
> {
> #ifdef BAD_SWAP
> // the following will swap in memory the two objects but will also
> deallocate/allocate/copy hugeStuff
> T tempData;
>
>
> tempData = *inDataPtr1;
> *inDataPtr1 = *inDataPtr2;
> *inDataPtr2 = tempData;
> #else
> // the following will just swap bitwise the members of the two
> objects without erasing/duplicating/whatever hugeStuff
> // but this bitwise copy seems to be slower than using the operator=
> (when it's not overloaded)
> // so I was wondering if it is possible to access the UNoverloaded
> operator= in objects that have overloaded it....
> char * aPtr;
>
>
> aPtr = (char*) malloc ( sizeof( T ) );
> memcpy( aPtr, inDataPtr1, sizeof( T ) );
> memcpy( inDataPtr1, inDataPtr2, sizeof( T ) );
> memcpy( inDataPtr2, aPtr, sizeof( T ) );
> free( aPtr );
> #endif
> }
>
>
> void main( void )
> {
> MyData * aDataPtr;
>
> aDataPtr = new MyData[ 100 ];
> FillUp( aDataPtr, 100 ); // filling up with data
> MySwap< MyData >( aDataPtr + 20, aDataPtr + 40 ); // just
> because.... :-)
> }
>
>
> Thanks in advance for any insight,
> Francesco
>
>
> On Apr 20, 2005, at 7:46 PM, Alfred P. Reaud wrote:
>
>
> Hi Francesco,
>
> Your array of class objects would be better served if it where a list or
> vector of class objects instead of an array. Then you can use the iterator
> features, including list and vector specific swap and sort member functions.
> I f you must use an array of class objects, then there's always the
> <algorithm> standard template library header. Algorithm has a rich set of
> functions that include swap, sort, and other useful data manipulation
> algorithms such as unique, etc. These functions are usually optimized, and
> work in most instances significantly better than manually coded swap or sort
> functions.
>
> I'm not actually sure what you mean by "deep copy", however, I'm assuming
> that you mean actual data copying. You shouldn't be copying data to swap
> it! You should be swapping pointers to the data. Maybe the issue is in
> using a class class_objects[array_size]; declaration vs. a class
> *class_objects; declaration, because the overloaded operator= may operate in
> a different fashion between a pointer and an array element (i.e.
> class_objects[7], is a pointer, but in machine code is actually a set of
> pointer arithmetic operations). The class operator= should already be
> configured to correctly do something like:
>
> class *obj_a, *obj_b, *temp;
> obj_a = new class; ...;
> temp = obj_a; obj_a = obj_b; obj_b = temp;
> delete(temp); ...
>
> so that should work correctly, ***** however *****
>
>
>
> list<class> obj_list;
> list<class>::iterator obj_iter;
> obj_list.push_back(obj_a); ...
> obj_iter = obj_list.begin();
> obj_list.sort() or obj_list.sort( compare_function );
> ...
>
> is easier, more elegant, and uses the optimized features of C++! Hopefully
> the above helps!
>
>
> Francesco <xtr...@vi...> wrote:
> Hi everybody,
> I'm a total beginner and I have the following problem:
> I have an array of objects instantiated from a class that has member
> pointers to dynamically allocated data. This class has also the usual
> overloaded operator=. I have to sort this array and I need to do some
> swapping. But swapping by "deep copy" seems useless to me in this case,
> thus is it possible somehow to override the overloaded operator= and
> use just for the swapping the normal operator =? I could use memcpy for
> a bitwise copy, but it seems to be significantly slower, especially
> for small objects.
> Thanks in advance,
> Francesco
> <snip>
>
>
>
>
> Alfred P. Reaud
> <image.tiff>
> ___________________________________________________________________
> The information contained in this message and any attachment may be
> proprietary, confidential, and privileged or subject to the work
> product doctrine and thus protected from disclosure. If the reader
> of this message is not the intended recipient, or an employee or
> agent responsible for delivering this message to the intended
> recipient, you are hereby notified that any dissemination,
> distribution or copying of this communication is strictly prohibited.
> If you have received this communication in error, please notify me
> immediately by replying to this message and deleting it and all
> copies and backups thereof. Thank you.
>
>
>
> -------------------------------------------------------
> SF email is sponsored by - The IT Product Guide
> Read honest & candid reviews on hundreds of IT Products from real users.
> Discover which products truly live up to the hype. Start reading now.
> http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www23.brinkster.com/noicys/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
|
|
From: <Mat...@Ve...> - 2005-04-21 18:53:22
|
Per,
You spent a _lot_ longer on that than I ever would have. :-) I was just
giving a quick general answer since I'm at work and in kind of a hurry to
finish up a big project. Yours was a really cool explanation. Thanks for
writing it. It taught me a lot about how memcpy really works.
I suppose that-- this observation is for the truly pedantic, you could seek
out its "official" implementations in the GLIBC source code. Don't you just
love the GPL? :-)
Regards,
Matt
-----Original Message-----
From: Per Westermark [mailto:pw...@ia...]
Sent: Thursday, April 21, 2005 11:01 AM
To: Mat...@Ve...
Cc: xtr...@vi...; al...@ya...;
dev...@li...
Subject: RE: [Dev-C++] Shallow copy
For small objects, an inlined copy function might be better, but for
larger blocks, the memcpy() function is optimized to switch over to 32-bit
(or larger) moves for maximum performance, i.e. it definitely wins over a
char* copy.
By the way, a couple of problems with the code:
No (char*)i - you wan't to declare i as a variable, not typecast it to
char*.
Second, avoid extra variables. Your code is using 4 variables. Instead of
creating a new variable i and do begin+i you should increment begin.
Besides using a variable less, it also optimizes the memory reference for
some processors.
A low-end memcpy() looks something like:
void* copy(void *dst,void *src,unsigned size) {
char* orig_dst = dst;
char* end = (char*)src + size;
while ((char*)src < end) {
*((char*)dst)++ = *((char*)src)++;
}
return orig_dst;
}
A normal memcpy() will do some optional single byte copies at start to get
word-aligned, and then do several unrolled word-copies (as large word as
possible, i.e. normally 32 or 64 bit) and then end with some optional
single-byte copies again.
If data is known to always be well-aligned and of a reasonable size, a
better code would be (pseudo-code):
void* copy(void *dst,void *src,unsigned size) {
// Observe: Code assumes that src and dst are aligned to sizeof(long)
// If they are not, one or more single-byte copy are needed...
void* orig_dst = dst;
unsigned r = size % sizeof(unsigned long);
unsigned count = size / sizeof(unsigned long);
if (size >= 4) {
// Unroll loop 4 times.
size >>= 2;
r += 4*sizeof(unsigned long);
} else {
// Too small block to unroll.
r += 4*size;
size = 0;
}
for (;size; size--) {
*((unsigned long*)dst)++ = *((unsigned long*)src)++;
*((unsigned long*)dst)++ = *((unsigned long*)src)++;
*((unsigned long*)dst)++ = *((unsigned long*)src)++;
*((unsigned long*)dst)++ = *((unsigned long*)src)++;
}
// r and this code not needed if size is a multiple of sizeof(long)
for (;r; r--) {
*((char*)dst)++ = *((char*)src)++;
}
return *orig_dst;
}
In reality, this kind of code is written in assembler, to allow further
optimizations by for example using calculated jumps into the unrolling
code. Also, some processors have special instructions for memory transfer
operations.
/Per W
On Thu, 21 Apr 2005 Mat...@Ve... wrote:
> Alright. Once you have overloaded an operator, you are stuck with that
> operator. However, overloaded operators apply on a class by class basis.
The
> HugeStuff type will not use the operator= that you defined for your class.
> Can you think of a way to refactor your operator= to operate in terms of
the
> default operator= define for type HugeStuff?
>
> Also, memcpy should be very fast. If it's not, try rolling your own. It
> might work something like the below code. Also make sure you enable -O3
> -fexpensive-optimizations when you build the code. You might also need
-mcpu
> and -mtune.
>
> Some routines benefit heavily from optimization. Copy-heavy routines seem
to
> need help with this. When I wrote a crypto algorithm a while ago, it
doubled
> the speed to optimize it fully.
>
> void copy(void* begin, void* end, void* dest)
> {
> for((char*) i=0; i<(char*)end; i++)
> {
> *(char*)dest=(char*)(begin+i);
> }
> }
>
> HTH!
> Matt
> -----Original Message-----
> From: dev...@li...
> [mailto:dev...@li...]On Behalf Of Francesco
> Sent: Thursday, April 21, 2005 3:02 AM
> To: Alfred P. Reaud
> Cc: Dev C++
> Subject: Re: [Dev-C++] Shallow copy
>
>
> Thanks for answering Alfred,
> I'm already using the STL but since I'm still in a learning stage I was
> trying to understand the "inner workings". Suppose I'm building ( just for
> my own pleasure :-) ) a simple competitor to the vector template. Or to
make
> it even more banal, suppose I have the following code:
>
>
> class MyData
> {
> typeHugeStuff * mHugeStuffPtr;
> // ....
> public:
> // ....
> MyData const & operator=( MyData const & inMyData ); // the
> definition of this copies also the stuff pointed to by mHugeStuffPtr
> // .....
> };
>
>
> template< typename T >
> void MySwap( T * inDataPtr1, T * inDataPtr2 )
> {
> #ifdef BAD_SWAP
> // the following will swap in memory the two objects but will also
> deallocate/allocate/copy hugeStuff
> T tempData;
>
>
> tempData = *inDataPtr1;
> *inDataPtr1 = *inDataPtr2;
> *inDataPtr2 = tempData;
> #else
> // the following will just swap bitwise the members of the two
> objects without erasing/duplicating/whatever hugeStuff
> // but this bitwise copy seems to be slower than using the
operator=
> (when it's not overloaded)
> // so I was wondering if it is possible to access the UNoverloaded
> operator= in objects that have overloaded it....
> char * aPtr;
>
>
> aPtr = (char*) malloc ( sizeof( T ) );
> memcpy( aPtr, inDataPtr1, sizeof( T ) );
> memcpy( inDataPtr1, inDataPtr2, sizeof( T ) );
> memcpy( inDataPtr2, aPtr, sizeof( T ) );
> free( aPtr );
> #endif
> }
>
>
> void main( void )
> {
> MyData * aDataPtr;
>
> aDataPtr = new MyData[ 100 ];
> FillUp( aDataPtr, 100 ); // filling up with data
> MySwap< MyData >( aDataPtr + 20, aDataPtr + 40 ); // just
> because.... :-)
> }
>
>
> Thanks in advance for any insight,
> Francesco
>
>
> On Apr 20, 2005, at 7:46 PM, Alfred P. Reaud wrote:
>
>
> Hi Francesco,
>
> Your array of class objects would be better served if it where a list or
> vector of class objects instead of an array. Then you can use the
iterator
> features, including list and vector specific swap and sort member
functions.
> I f you must use an array of class objects, then there's always the
> <algorithm> standard template library header. Algorithm has a rich set of
> functions that include swap, sort, and other useful data manipulation
> algorithms such as unique, etc. These functions are usually optimized,
and
> work in most instances significantly better than manually coded swap or
sort
> functions.
>
> I'm not actually sure what you mean by "deep copy", however, I'm assuming
> that you mean actual data copying. You shouldn't be copying data to swap
> it! You should be swapping pointers to the data. Maybe the issue is in
> using a class class_objects[array_size]; declaration vs. a class
> *class_objects; declaration, because the overloaded operator= may operate
in
> a different fashion between a pointer and an array element (i.e.
> class_objects[7], is a pointer, but in machine code is actually a set of
> pointer arithmetic operations). The class operator= should already be
> configured to correctly do something like:
>
> class *obj_a, *obj_b, *temp;
> obj_a = new class; ...;
> temp = obj_a; obj_a = obj_b; obj_b = temp;
> delete(temp); ...
>
> so that should work correctly, ***** however *****
>
>
>
> list<class> obj_list;
> list<class>::iterator obj_iter;
> obj_list.push_back(obj_a); ...
> obj_iter = obj_list.begin();
> obj_list.sort() or obj_list.sort( compare_function );
> ...
>
> is easier, more elegant, and uses the optimized features of C++!
Hopefully
> the above helps!
>
>
> Francesco <xtr...@vi...> wrote:
> Hi everybody,
> I'm a total beginner and I have the following problem:
> I have an array of objects instantiated from a class that has member
> pointers to dynamically allocated data. This class has also the usual
> overloaded operator=. I have to sort this array and I need to do some
> swapping. But swapping by "deep copy" seems useless to me in this case,
> thus is it possible somehow to override the overloaded operator= and
> use just for the swapping the normal operator =? I could use memcpy for
> a bitwise copy, but it seems to be significantly slower, especially
> for small objects.
> Thanks in advance,
> Francesco
> <snip>
>
>
>
>
> Alfred P. Reaud
> <image.tiff>
> ___________________________________________________________________
> The information contained in this message and any attachment may be
> proprietary, confidential, and privileged or subject to the work
> product doctrine and thus protected from disclosure. If the reader
> of this message is not the intended recipient, or an employee or
> agent responsible for delivering this message to the intended
> recipient, you are hereby notified that any dissemination,
> distribution or copying of this communication is strictly prohibited.
> If you have received this communication in error, please notify me
> immediately by replying to this message and deleting it and all
> copies and backups thereof. Thank you.
>
>
>
> -------------------------------------------------------
> SF email is sponsored by - The IT Product Guide
> Read honest & candid reviews on hundreds of IT Products from real users.
> Discover which products truly live up to the hype. Start reading now.
> http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www23.brinkster.com/noicys/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
|
|
From: Francesco <xtr...@vi...> - 2005-04-21 20:48:13
|
Thanks to everybody for the in-depth explanations.
Francesco
On Apr 21, 2005, at 7:04 PM, Mat...@Ve... wrote:
> Alright. Once you have overloaded an operator, you are stuck with that
> operator. However, overloaded operators apply on a class by class
> basis. The
> HugeStuff type will not use the operator= that you defined for your
> class.
> Can you think of a way to refactor your operator= to operate in terms
> of the
> default operator= define for type HugeStuff?
>
> Also, memcpy should be very fast. If it's not, try rolling your own. It
> might work something like the below code. Also make sure you enable -O3
> -fexpensive-optimizations when you build the code. You might also need
> -mcpu
> and -mtune.
>
> Some routines benefit heavily from optimization. Copy-heavy routines
> seem to
> need help with this. When I wrote a crypto algorithm a while ago, it
> doubled
> the speed to optimize it fully.
>
> void copy(void* begin, void* end, void* dest)
> {
> for((char*) i=0; i<(char*)end; i++)
> {
> *(char*)dest=(char*)(begin+i);
> }
> }
>
> HTH!
> Matt
> -----Original Message-----
> From: dev...@li...
> [mailto:dev...@li...]On Behalf Of
> Francesco
> Sent: Thursday, April 21, 2005 3:02 AM
> To: Alfred P. Reaud
> Cc: Dev C++
> Subject: Re: [Dev-C++] Shallow copy
>
>
> Thanks for answering Alfred,
> I'm already using the STL but since I'm still in a learning stage I was
> trying to understand the "inner workings". Suppose I'm building ( just
> for
> my own pleasure :-) ) a simple competitor to the vector template. Or
> to make
> it even more banal, suppose I have the following code:
>
>
> class MyData
> {
> typeHugeStuff * mHugeStuffPtr;
> // ....
> public:
> // ....
> MyData const & operator=( MyData const & inMyData ); // the
> definition of this copies also the stuff pointed to by mHugeStuffPtr
> // .....
> };
>
>
> template< typename T >
> void MySwap( T * inDataPtr1, T * inDataPtr2 )
> {
> #ifdef BAD_SWAP
> // the following will swap in memory the two objects but will
> also
> deallocate/allocate/copy hugeStuff
> T tempData;
>
>
> tempData = *inDataPtr1;
> *inDataPtr1 = *inDataPtr2;
> *inDataPtr2 = tempData;
> #else
> // the following will just swap bitwise the members of the two
> objects without erasing/duplicating/whatever hugeStuff
> // but this bitwise copy seems to be slower than using the
> operator=
> (when it's not overloaded)
> // so I was wondering if it is possible to access the
> UNoverloaded
> operator= in objects that have overloaded it....
> char * aPtr;
>
>
> aPtr = (char*) malloc ( sizeof( T ) );
> memcpy( aPtr, inDataPtr1, sizeof( T ) );
> memcpy( inDataPtr1, inDataPtr2, sizeof( T ) );
> memcpy( inDataPtr2, aPtr, sizeof( T ) );
> free( aPtr );
> #endif
> }
>
>
> void main( void )
> {
> MyData * aDataPtr;
>
> aDataPtr = new MyData[ 100 ];
> FillUp( aDataPtr, 100 ); // filling up with data
> MySwap< MyData >( aDataPtr + 20, aDataPtr + 40 ); // just
> because.... :-)
> }
>
>
> Thanks in advance for any insight,
> Francesco
>
>
> On Apr 20, 2005, at 7:46 PM, Alfred P. Reaud wrote:
>
>
> Hi Francesco,
>
> Your array of class objects would be better served if it where a list
> or
> vector of class objects instead of an array. Then you can use the
> iterator
> features, including list and vector specific swap and sort member
> functions.
> I f you must use an array of class objects, then there's always the
> <algorithm> standard template library header. Algorithm has a rich
> set of
> functions that include swap, sort, and other useful data manipulation
> algorithms such as unique, etc. These functions are usually
> optimized, and
> work in most instances significantly better than manually coded swap
> or sort
> functions.
>
> I'm not actually sure what you mean by "deep copy", however, I'm
> assuming
> that you mean actual data copying. You shouldn't be copying data to
> swap
> it! You should be swapping pointers to the data. Maybe the issue is
> in
> using a class class_objects[array_size]; declaration vs. a class
> *class_objects; declaration, because the overloaded operator= may
> operate in
> a different fashion between a pointer and an array element (i.e.
> class_objects[7], is a pointer, but in machine code is actually a set
> of
> pointer arithmetic operations). The class operator= should already be
> configured to correctly do something like:
>
> class *obj_a, *obj_b, *temp;
> obj_a = new class; ...;
> temp = obj_a; obj_a = obj_b; obj_b = temp;
> delete(temp); ...
>
> so that should work correctly, ***** however *****
>
>
>
> list<class> obj_list;
> list<class>::iterator obj_iter;
> obj_list.push_back(obj_a); ...
> obj_iter = obj_list.begin();
> obj_list.sort() or obj_list.sort( compare_function );
> ...
>
> is easier, more elegant, and uses the optimized features of C++!
> Hopefully
> the above helps!
>
>
> Francesco <xtr...@vi...> wrote:
> Hi everybody,
> I'm a total beginner and I have the following problem:
> I have an array of objects instantiated from a class that has member
> pointers to dynamically allocated data. This class has also the usual
> overloaded operator=. I have to sort this array and I need to do some
> swapping. But swapping by "deep copy" seems useless to me in this case,
> thus is it possible somehow to override the overloaded operator= and
> use just for the swapping the normal operator =? I could use memcpy for
> a bitwise copy, but it seems to be significantly slower, especially
> for small objects.
> Thanks in advance,
> Francesco
> <snip>
>
>
>
>
> Alfred P. Reaud
> <image.tiff>
> ___________________________________________________________________
> The information contained in this message and any attachment may be
> proprietary, confidential, and privileged or subject to the work
> product doctrine and thus protected from disclosure. If the reader
> of this message is not the intended recipient, or an employee or
> agent responsible for delivering this message to the intended
> recipient, you are hereby notified that any dissemination,
> distribution or copying of this communication is strictly prohibited.
> If you have received this communication in error, please notify me
> immediately by replying to this message and deleting it and all
> copies and backups thereof. Thank you.
>
|
|
From: Francesco <xtr...@vi...> - 2005-04-21 09:54:49
|
Thanks for answering Alfred,
I'm already using the STL but since I'm still in a learning stage I was=20=
trying to understand the "inner workings". Suppose I'm building ( just=20=
for my own pleasure :-) ) a simple competitor to the vector template.=20=
Or to make it even more banal, suppose I have the following code:
class MyData
{
typeHugeStuff * mHugeStuffPtr;
// ....
public:
// ....
MyData const & operator=3D( MyData const & inMyData ); // the =
definition=20
of this copies also the stuff pointed to by mHugeStuffPtr
// .....
};
template< typename T >
void MySwap( T * inDataPtr1, T * inDataPtr2 )
{
#ifdef BAD_SWAP
// the following will swap in memory the two objects but will =
also=20
deallocate/allocate/copy hugeStuff
T tempData;
tempData =3D *inDataPtr1;
*inDataPtr1 =3D *inDataPtr2;
*inDataPtr2 =3D tempData;
#else
// the following will just swap bitwise the members of the two =
objects=20
without erasing/duplicating/whatever hugeStuff
// but this bitwise copy seems to be slower than using the =
operator=3D=20
(when it's not overloaded)
// so I was wondering if it is possible to access the =
UNoverloaded=20
operator=3D in objects that have overloaded it....
char * aPtr;
aPtr =3D (char*) malloc ( sizeof( T ) );
memcpy( aPtr, inDataPtr1, sizeof( T ) );
memcpy( inDataPtr1, inDataPtr2, sizeof( T ) );
memcpy( inDataPtr2, aPtr, sizeof( T ) );
free( aPtr );
#endif
}
void main( void )
{
MyData * aDataPtr;
=09
aDataPtr =3D new MyData[ 100 ];
FillUp( aDataPtr, 100 ); // filling up with data
MySwap< MyData >( aDataPtr + 20, aDataPtr + 40 ); // just =
because.... =20
:-)
}
Thanks in advance for any insight,
Francesco
On Apr 20, 2005, at 7:46 PM, Alfred P. Reaud wrote:
> Hi Francesco,
> =A0
> Your array of class objects would be better served if it where a list=20=
> or vector of class objects instead of an array.=A0 Then you can use =
the=20
> iterator features, including list and vector specific swap and sort=20
> member functions.=A0 I f you must use an array of class objects, =
then=20
> there's always the <algorithm> standard template library header.=A0=20
> Algorithm has a rich set of functions that include swap, sort, and=20
> other useful data manipulation algorithms such as unique, etc.=A0 =
These=20
> functions are usually optimized, and work in most instances=20
> significantly better than manually coded swap or sort functions.
> =A0
> I'm not actually sure what you mean by "deep copy", however, I'm=20
> assuming that you mean actual data copying.=A0 You shouldn't be =
copying=20
> data to swap it!=A0 You should be swapping pointers to the data.=A0 =
Maybe=20
> the issue is in using a class class_objects[array_size]; declaration=20=
> vs. a class *class_objects; declaration, because the overloaded=20
> operator=3D may operate in a different fashion between a pointer and =
an=20
> array element (i.e. class_objects[7], is a pointer, but in machine=20
> code is actually a set of pointer arithmetic operations).=A0 The class=20=
> operator=3D should already be configured to correctly do something =
like:
> =A0
> class *obj_a, *obj_b, *temp;
> obj_a =3D new class; ...;
> temp =3D obj_a; obj_a =3D obj_b; obj_b =3D temp;
> delete(temp); ...
> =A0
> so that should work correctly, ***** however *****
> =A0
>
> list<class> obj_list;
> list<class>::iterator obj_iter;
> obj_list.push_back(obj_a); ...
> obj_iter =3D obj_list.begin();
> obj_list.sort() or obj_list.sort( compare_function );
> ...
> =A0
> is easier, more elegant, and uses the optimized features of C++!=A0=20
> Hopefully the above helps!
>
> Francesco <xtr...@vi...> wrote:
> Hi everybody,
> I'm a total beginner and I have the following problem:
> I have an array of objects instantiated from a class that has member
> pointers to dynamically allocated data. This class has also the usual
> overloaded operator=3D. I have to sort this array and I need to do =
some
> swapping. But swapping by "deep copy" seems useless to me in this=20
> case,
> thus is it possible somehow to override the overloaded operator=3D =
and
> use just for the swapping the normal operator =3D? I could use memcpy=20=
> for
> a bitwise copy, but it seems to be significantly slower, especially
> for small objects.
> Thanks in advance,
> Francesco
> <snip>
>
>
>
> Alfred P. Reaud
> <image.tiff>
|