Concatenating strings in C, which method is more efficient? Concatenating strings in C, which method is more efficient? c c

Concatenating strings in C, which method is more efficient?


For readability, I'd go with

char * s = malloc(snprintf(NULL, 0, "%s %s", first, second) + 1);sprintf(s, "%s %s", first, second);

If your platform supports GNU extensions, you could also use asprintf():

char * s = NULL;asprintf(&s, "%s %s", first, second);

If you're stuck with the MS C Runtime, you have to use _scprintf() to determine the length of the resulting string:

char * s = malloc(_scprintf("%s %s", first, second) + 1);sprintf(s, "%s %s", first, second);

The following will most likely be the fastest solution:

size_t len1 = strlen(first);size_t len2 = strlen(second);char * s = malloc(len1 + len2 + 2);memcpy(s, first, len1);s[len1] = ' ';memcpy(s + len1 + 1, second, len2 + 1); // includes terminating null


Don't worry about efficiency: make your code readable and maintainable. I doubt the difference between these methods is going to matter in your program.


Here's some madness for you, I actually went and measured it. Bloody hell, imagine that. I think I got some meaningful results.

I used a dual core P4, running Windows, using mingw gcc 4.4, building with "gcc foo.c -o foo.exe -std=c99 -Wall -O2".

I tested method 1 and method 2 from the original post. Initially kept the malloc outside the benchmark loop. Method 1 was 48 times faster than method 2. Bizarrely, removing -O2 from the build command made the resulting exe 30% faster (haven't investigated why yet).

Then I added a malloc and free inside the loop. That slowed down method 1 by a factor of 4.4. Method 2 slowed down by a factor of 1.1.

So, malloc + strlen + free DO NOT dominate the profile enough to make avoiding sprintf worth while.

Here's the code I used (apart from the loops were implemented with < instead of != but that broke the HTML rendering of this post):

void a(char *first, char *second, char *both){    for (int i = 0; i != 1000000 * 48; i++)    {        strcpy(both, first);        strcat(both, " ");        strcat(both, second);    }}void b(char *first, char *second, char *both){    for (int i = 0; i != 1000000 * 1; i++)        sprintf(both, "%s %s", first, second);}int main(void){    char* first= "First";    char* second = "Second";    char* both = (char*) malloc((strlen(first) + strlen(second) + 2) * sizeof(char));    // Takes 3.7 sec with optimisations, 2.7 sec WITHOUT optimisations!    a(first, second, both);    // Takes 3.7 sec with or without optimisations    //b(first, second, both);    return 0;}