FASTER string copy ????

A

akarui.tomodachi

I have two structure definitions as below:

typedef struct _sourceString
{
char firstSourceString[20];
char secondSourceString[20];
char thirdSourceString[20];
}sourceString;


typedef struct _destinString
{
char firstDestinString[20];
char secondDestinString[20];
char thirdDestinString[20];
}destinString;

in the code.......
/********************
sourceString* mySource;
destinString* myDestin;

mySource->firstSourceString = "ABC 123";
mySource->secondSourceString = "ABC 123";
mySource->thirdSourceString = "ABC 123";

strcpy(myDestin->firstDestinString, mySource->firstSourceString);
strcpy(myDestin->secondDestinString, mySource->secondSourceString);
strcpy(myDestin->thirdDestinString, mySource->thirdSourceString);
**********************/

The above "strcpy" is ok until I ported this code to a small embedded
system, where TIME is a critical factor. This type of copying by using
"strcpy" takes longer process time and creates all bunch of problems
related to delay.

However, how can I copy my source strings to the destination string
buffers without using strcpy (or memcpy) faster ?
 
R

Richard Heathfield

(e-mail address removed) said:
However, how can I copy my source strings to the destination string
buffers without using strcpy (or memcpy) faster ?

If you can beat a platform-optimised memcpy, you'll be doing *really* well.
The memcpy function is generally optimised to the hilt.
 
E

Eric Sosman

I have two structure definitions as below:

typedef struct _sourceString
{
char firstSourceString[20];
char secondSourceString[20];
char thirdSourceString[20];
}sourceString;


typedef struct _destinString
{
char firstDestinString[20];
char secondDestinString[20];
char thirdDestinString[20];
}destinString;

Seems rather silly to have two different struct types
with identical content. Not illegal, just silly.
in the code.......
/********************
sourceString* mySource;
destinString* myDestin;

mySource->firstSourceString = "ABC 123";

This is an error in Standard C: the l.h.s. is an array,
and arrays are not assignable. If your compiler accepted
this, it is operating in some kind of "pseudo-C" mode.
mySource->secondSourceString = "ABC 123";
mySource->thirdSourceString = "ABC 123";

strcpy(myDestin->firstDestinString, mySource->firstSourceString);
strcpy(myDestin->secondDestinString, mySource->secondSourceString);
strcpy(myDestin->thirdDestinString, mySource->thirdSourceString);
**********************/

The above "strcpy" is ok until I ported this code to a small embedded
system, where TIME is a critical factor. This type of copying by using
"strcpy" takes longer process time and creates all bunch of problems
related to delay.

However, how can I copy my source strings to the destination string
buffers without using strcpy (or memcpy) faster ?

I have no idea. If your code is really as you have shown,
the language you are using isn't C and I cannot tell what the
program is doing. And if your code *isn't* as you have shown,
well then, I *still* cannot tell what the program is doing!

... besides which, the C language says nothing about the
speeds of various constructs, and the speeds (both absolute and
relative) will vary from one implementation to another. The only
reliable way to determine the speed of some operation is to
measure how long it takes -- and keep in mind that the measurement
is only valid on the system where you made it, with the compiler
version and flags that you used, and in the program where you
used them. Change anything, and your measurements become suspect
if not completely invalid.
 
S

suresh

I have two structure definitions as below:

typedef struct _sourceString
{
char firstSourceString[20];
char secondSourceString[20];
char thirdSourceString[20];
}sourceString;


typedef struct _destinString
{
char firstDestinString[20];
char secondDestinString[20];
char thirdDestinString[20];
}destinString;

in the code.......
/********************
sourceString* mySource;
destinString* myDestin;

mySource->firstSourceString = "ABC 123";

Compiler error : Not an L value
Undefined behavior : Un initialised pointer accessed.
mySource->secondSourceString = "ABC 123";
ditto

mySource->thirdSourceString = "ABC 123";

ditto

Post the original (minimal compilable) code.
strcpy(myDestin->firstDestinString, mySource->firstSourceString);
strcpy(myDestin->secondDestinString, mySource->secondSourceString);
strcpy(myDestin->thirdDestinString, mySource->thirdSourceString);
**********************/

The above "strcpy" is ok until I ported this code to a small embedded
system, where TIME is a critical factor. This type of copying by using
"strcpy" takes longer process time and creates all bunch of problems
related to delay.

However, how can I copy my source strings to the destination string
buffers without using strcpy (or memcpy) faster ?


I dont think you can write a function that is faster than what the
compiler provides for this case. You can avoid the call to strcpy by
just assigning the structures.

*myDestin = *mySource

This may not be efficient because it will copy all the contents in one
structure to the other. Whereas strcpy copies only the characters up to
NUL.

If you want more efficient code consider redesigning. Try avoiding
unnecessary copies and the like.
 
W

William Ahern

The above "strcpy" is ok until I ported this code to a small embedded
system, where TIME is a critical factor. This type of copying by using
"strcpy" takes longer process time and creates all bunch of problems
related to delay.

However, how can I copy my source strings to the destination string
buffers without using strcpy (or memcpy) faster ?

memcpy() will likely be the fastest way you could copy anything to
anywhere for general purpose opaque data.

What's even faster than copying with memcpy() is not copying at all,
so called "zero-copy". With that methodology you simply pass pointers to
your buffers around. It's rather difficult to do, though, especially if
your design didn't incorporate the notion from the beginning. When you
start contemplating reference counting or some such device it's probably
too late in the design cycle (unless the purpose of the device is
specific, and the scope of use limited).

The simper way is for ownership of the buffer to implicitly pass to the
various functions, but that requires careful attention to the flow of
logic.
 
J

John Tsiombikas (Nuclear / Mindlapse)

If you can beat a platform-optimised memcpy, you'll be doing *really* well.
The memcpy function is generally optimised to the hilt.

Not always true. For example, I've done some programming on the nintendo
gameboy advance, and the memcpy() provided by newlib (an
embedded-oriented libc) when compiled with target=arm-agb-elf does *not*
use the DMA circuitry of the gba. So if you use that, you get much
faster memory copies.

But that's a pathological case, I do agree that in general memcpy tends
to be very optimized, and the best choice.
 
R

Richard Heathfield

John Tsiombikas (Nuclear / Mindlapse) said:
Not always true. For example, I've done some programming on the nintendo
gameboy advance, and the memcpy() provided by newlib (an
embedded-oriented libc) when compiled with target=arm-agb-elf does *not*
use the DMA circuitry of the gba. So if you use that, you get much
faster memory copies.

If that is the case, then it isn't platform-optimised. Any fool can write a
/slow/ memcpy:

volatile time_t _lets_waste_time;void*memcpy(void*t,const void*s,size_t n)
{void*u=t;size_t i;while(n--){for(i=0;i<n;i++)_lets_waste_time=time(NULL);
((unsigned char*)t)[n]=((unsigned char*)s)[n];}return u;}

or some such nonsense. This doesn't affect my argument in the slightest.
 
J

John Tsiombikas (Nuclear / Mindlapse)

John Tsiombikas (Nuclear / Mindlapse) said:
Not always true. For example, I've done some programming on the nintendo
gameboy advance, and the memcpy() provided by newlib (an
embedded-oriented libc) when compiled with target=arm-agb-elf does *not*
use the DMA circuitry of the gba. So if you use that, you get much
faster memory copies.

If that is the case, then it isn't platform-optimised. Any fool can write a
/slow/ memcpy:

volatile time_t _lets_waste_time;void*memcpy(void*t,const void*s,size_t n)
{void*u=t;size_t i;while(n--){for(i=0;i<n;i++)_lets_waste_time=time(NULL);
((unsigned char*)t)[n]=((unsigned char*)s)[n];}return u;}

or some such nonsense. This doesn't affect my argument in the slightest.

I didn't say it does. I just said that in general what you said is true,
and memcpy is indeed optimized "to the hilt" as you put it, but there
are cases where the memcpy provided might not be platform-optimized, and
it would be a good idea for one to check that first, if memory copy
speed is essential.
 
R

Richard Heathfield

John Tsiombikas (Nuclear / Mindlapse) said:
I didn't say it does. I just said that in general what you said is true,
and memcpy is indeed optimized "to the hilt" as you put it, but there
are cases where the memcpy provided might not be platform-optimized, and
it would be a good idea for one to check that first, if memory copy
speed is essential.

Yes, fair enough.
 
A

akarui.tomodachi

Hi Eric,
You are right, I didn't put the proper syntax in assignment to the
string buffer. The excat code is here:

typedef struct _sourceString
{
char firstSourceString[20];
char secondSourceString[20];
char thirdSourceString[20];

}sourceString;

typedef struct _destinString
{
char firstDestinString[20];
char secondDestinString[20];
char thirdDestinString[20];

}destinString;

in the code.......
/********************
sourceString* mySource;
destinString* myDestin;

sprintf(mySource->firstSourceString, "%s", "ABC 123");
sprintf(mySource->secondSourceString,"%s", "ABC 123");
sprintf(mySource->thirdSourceString, "%s", "ABC 123");

strcpy(myDestin->firstDestinString, mySource->firstSourceString);
strcpy(myDestin->secondDestinString, mySource->secondSourceString);
strcpy(myDestin->thirdDestinString, mySource->thirdSourceString);
**********************/
 
E

Eric Sosman

(e-mail address removed) wrote On 03/17/06 10:52,:

For future reference: Include some context when you
reply to a message on Usenet. Some people will not have
seen the message you are replying to, and will have no
idea what you're talking about.
Hi Eric,
You are right, I didn't put the proper syntax in assignment to the
string buffer. The excat code is here:

typedef struct _sourceString
{
char firstSourceString[20];
char secondSourceString[20];
char thirdSourceString[20];

}sourceString;

typedef struct _destinString
{
char firstDestinString[20];
char secondDestinString[20];
char thirdDestinString[20];

}destinString;

in the code.......
/********************
sourceString* mySource;
destinString* myDestin;

I'll assume that `mySource' is assigned to point to
an actual `sourceString' instance before the sprintf()
calls, and similarly for `myDestin' before strcpy().
sprintf(mySource->firstSourceString, "%s", "ABC 123");
sprintf(mySource->secondSourceString,"%s", "ABC 123");
sprintf(mySource->thirdSourceString, "%s", "ABC 123");

strcpy(myDestin->firstDestinString, mySource->firstSourceString);
strcpy(myDestin->secondDestinString, mySource->secondSourceString);
strcpy(myDestin->thirdDestinString, mySource->thirdSourceString);
**********************/

There is a faint chance that

memcpy(myDestin->firstDestinString,
mySource->firstSourceString,
sizeof(myDestin->firstDestinString);

.... etc., might be faster: the termination condition for
memcpy() is simpler than that for strcpy(), which might
speed it up slightly. On the other hand, the strcpy()
calls in your example will all stop after copying eight
characters, while each memcpy() would move twelve extra
and unnecessary characters. The only way to tell which
is faster is to measure under actual conditions.

Again, I draw your attention to the fact that the two
structs are identical except for a few names. If instead
you used the same struct type for both the source and the
destination, another approach would be available:

typedef struct {
char firstString[20];
char secondString[20];
char thirdString[20];
} String;

String *mySource = ...;
String *myDestin = ...;
...
*myDestin = *mySource; /* copy everything */

Whether this would be faster or slower is a subject for
more measurements.

Finally, if copying short strings is a performance
problem for your program, it is likely that your program
is copying too many of them. Do you really need to make
so many copies? Can't you arrange to create the strings
"already in place" where they're going to be needed, or
to keep pointers to where they were created instead of
copying them somewhere else? "Copying" doesn't usually
advance the state of a computation very much ...
 
M

Michel Bardiaux

Richard said:
John Tsiombikas (Nuclear / Mindlapse) said:

Actually, there is at least one major platform where memcpy is *not*
optimized to the hilt: the most recent runtime for gcc on i686 does
*not* use SIMD instructions, hence is (according to my
seat-of-the-pants-o-meter) twice as slow as it could be (benchmarking
memcpy is not easy because of caching effects).

Now, what *is* the CPU of the 'small embedded system' in question?
but there


Yes, fair enough.


--
Michel Bardiaux
R&D Director
T +32 [0] 2 790 29 41
F +32 [0] 2 790 29 02
E mailto:[email protected]

Mediaxim NV/SA
Vorstlaan 191 Boulevard du Souverain
Brussel 1160 Bruxelles
http://www.mediaxim.com/
 

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

No members online now.

Forum statistics

Threads
474,176
Messages
2,570,947
Members
47,498
Latest member
log5Sshell/alfa5

Latest Threads

Top