473,406 Members | 2,378 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

FASTER string copy ????

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 ?

Mar 17 '06 #1
11 4125
ak**************@gmail.com 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.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Mar 17 '06 #2
ak**************@gmail.com wrote:
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.

--
Eric Sosman
es*****@acm-dot-org.invalid
Mar 17 '06 #3
ak**************@gmail.com wrote:
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.

Mar 17 '06 #4
On Thu, 16 Mar 2006 20:34:05 -0800, akarui.tomodachi wrote:

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.
Mar 17 '06 #5
On 2006-03-17, Richard Heathfield <in*****@invalid.invalid> wrote:
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.

--
John Tsiombikas (Nuclear / Mindlapse)
nu*****@siggraph.org
http://nuclear.demoscene.gr/
Mar 17 '06 #6
John Tsiombikas (Nuclear / Mindlapse) said:
On 2006-03-17, Richard Heathfield <in*****@invalid.invalid> wrote:
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.


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.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Mar 17 '06 #7
On 2006-03-17, Richard Heathfield <in*****@invalid.invalid> wrote:
John Tsiombikas (Nuclear / Mindlapse) said:
On 2006-03-17, Richard Heathfield <in*****@invalid.invalid> wrote:
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.


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.

--
John Tsiombikas (Nuclear / Mindlapse)
nu*****@siggraph.org
http://nuclear.demoscene.gr/
Mar 17 '06 #8
John Tsiombikas (Nuclear / Mindlapse) said:
On 2006-03-17, Richard Heathfield <in*****@invalid.invalid> wrote:

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.


Yes, fair enough.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Mar 17 '06 #9
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);
**********************/

Mar 17 '06 #10


ak**************@gmail.com 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 ...

--
Er*********@sun.com

Mar 17 '06 #11
Richard Heathfield wrote:
John Tsiombikas (Nuclear / Mindlapse) said:

On 2006-03-17, Richard Heathfield <in*****@invalid.invalid> wrote:
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,


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
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.

--
Michel Bardiaux
R&D Director
T +32 [0] 2 790 29 41
F +32 [0] 2 790 29 02
E mailto:mb*******@mediaxim.be

Mediaxim NV/SA
Vorstlaan 191 Boulevard du Souverain
Brussel 1160 Bruxelles
http://www.mediaxim.com/
Mar 20 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

23
by: YinTat | last post by:
Hi, I learned C++ recently and I made a string class. A code example is this: class CString { public: inline CString(const char *rhs) { m_size = strlen(rhs);
98
by: jrefactors | last post by:
I heard people saying prefix increment is faster than postfix incerement, but I don't know what's the difference. They both are i = i+1. i++ ++i Please advise. thanks!!
43
by: Mountain Bikn' Guy | last post by:
I have a situation where an app writes data of various types (primitives and objects) into a single dimensional array of objects. (This array eventually becomes a row in a data table, but that's...
9
by: VenuGopal | last post by:
Hi, why n++ executes faster than n+1..... or does it realli execute faster? thanks Venugopal.B
13
by: Niyazi | last post by:
Hi I have a report that I have to run it monthly in my machine. My code in VB.NET and I access AS400 to get data, anaysie it and send into pre formated Excel sheet. The data consist of 9000...
9
by: Russell Mangel | last post by:
Can someone show me how to speed this up? 1. Whats the fastest way for Unsafe C#? 2. What the fastest way for Safe C#? public static Int64 ToInt64(Int32 low, Int32 high) { Byte lowBytes =...
34
by: raylopez99 | last post by:
StringBuilder better and faster than string for adding many strings. Look at the below. It's amazing how much faster StringBuilder is than string. The last loop below is telling: for adding...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.