Fastest way to get null char in copied string in C

I need to get a pointer to the terminating null char of a string.

I am currently using this simple method: MyString + strlen(MyString) , which is probably pretty good out of context.

However, this solution is not convenient for me, since I have to do it after a string copy:

 char MyString[32]; char* EndOfString; strcpy(MyString, "Foo"); EndOfString = MyString + strlen(MyString); 

So, I repeat the line around the line twice, the first time in strcpy and the second time in strlen .

I would like to avoid this overhead with a special function that returns the number of characters copied:

 size_t strcpylen(char *strDestination, const char *strSource) { size_t len = 0; while( *strDestination++ = *strSource++ ) len++; return len; } EndOfString = MyString + strcpylen(MyString, "Foobar"); 

However, I fear that my implementation may be slower than the CRT function provided by the compiler (which may use some assembly optimization or another trick instead of a simple char -by-char loop). Or maybe I donโ€™t know of any standard built-in function that already does this?


I benchmarked poor people, iterating 0x1FFFFFFF times three algorithms ( strcpy + strlen , my version is strcpylen and version is user434507 ). Result:

1) strcpy + strlen is the winner in just 967 milliseconds;

2) my version takes much longer: 57 seconds!

3) the edited version takes 53 seconds.

Thus, using two CRT functions instead of a custom โ€œoptimizedโ€ version in my environment is more than 50 times faster!

+4
source share
8 answers
 size_t strcpylen(char *strDestination, const char *strSource) { char* dest = strDestination; while( *dest++ = *strSource++ ); return dest - strDestination; } 

This is almost what the CRT version of strcpy does, except that the CRT version will also do some validation, for example. so that both arguments are not empty.

Edit: I am looking at the source of CRT for VC ++ 2005. pmg is correct, there is no verification. There are two versions of strcpy. One is written in the assembly, the other in C. Here's the C version:

 char * __cdecl strcpy(char * dst, const char * src) { char * cp = dst; while( *cp++ = *src++ ) ; /* Copy src over dst */ return( dst ); } 
+5
source

Hacker Delight has a nice section on finding the first null byte in string C (see chapter 6, section 1). I found (parts) of it in Google Books , and the code seems to be. I always come back to this book. Hope this will be helpful.

+5
source

Use strlcpy() , which will return the length of what it copied (assuming your size parameter is large enough).

+1
source

You can try the following:

 int len = strlen(new_str); memcpy(MyString, new_str, len + 1); EndOfString = MyString + len; 

This only makes sense if new_str large, because memcpy much faster than the standard while( *dest++ = *strSource++ ); , but has additional initialization costs.

+1
source

Just a few notes: if your function is not called very often, it can work faster from your code than from the C library, because your code is already in the processor caches.

What you do is make sure that the library call is in the cache, and this is not necessary in a real application.

In addition, Being built-in can even save more cycles: compilers and processors prefer sheet function calls (single-level encapsulation rather than multiple call levels) for branch prediction and data prefetching.

It depends on your code style, your application, and the need to keep loops.

As you can see, the image is a bit more complicated than before.

+1
source

I think you can worry too much here. Probably any possible profit you can make here will be more than offset by the best improvements you can make elsewhere. My advice would be to not worry about this, complete your code and see if you have enough processing cycles, that the advantage of this optimization outweighs the extra work and future maintenance efforts to speed it up.

In short: do not do this.

0
source

Try memccpy() (or _memccpy() in VC 2005+). I did some tests with strcpy + strlen and your custom algorithm, and in my environment it beat both. I donโ€™t know how well it will work in yours, though, since for me your algorithm works much faster than you saw, and strcpy + strlen much slower (14.4s for the former versus 7.3 for the latter, using your iteration number). I programmed the code below for about 5 seconds.

 int main(int argc, char *argv[]) { char test_string[] = "Foo"; char new_string[64]; char *null_character = NULL; int i; int iterations = 0x1FFFFFFF; for(i = 0; i < iterations; i++) { null_character = memccpy(new_string, test_string, 0, 64); --null_character; } return 0; } 
0
source

All Articles