String copy function memcpy and strncpy and snprintf performance comparison
- 2020-04-02 01:11:22
- OfStack
Question:
The functions memcpy(dest, SRC, sizeof(dest)), strncpy(dest, SRC, sizeof(dest)), and snprintf(dest, sizeof(dest), "%s", SRC) can all copy the contents of the SRC string into the dest string.
Which is the most efficient way?
That is, what works best?
Solutions:
1. Create three files test_memcpy.c, test_strncpy.c and test_snprintf.c:
File test_memcpy. C:
david@u1110-hp:~/wrk/tmp/cstring$ cat test_memcpy.c
#include <string.h>
int main(){
char src[] = "1234567890";
char dest[2048];
int len = 0;
for(int i = 0; i < 10000000; ++i){
memset(dest, 0, sizeof(dest));
len = strlen(src);
len = sizeof(dest) - 1 > len? len: sizeof(dest) -1;
memcpy(dest, src, len);
dest[len] = '0';
}
return 0;
}
File test_strncpy. C:
#include <string.h>
int main() {
char src[] = "1234567890";
char dest[2048];
int len = 0;
for(int i = 0; i < 10000000; ++i) {
memset(dest, 0, sizeof(dest));
strncpy(dest, src, sizeof(dest));
}
return 0;
}
File test_snprintf. C:
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "1234567890";
char dest[2048];
int len = 0;
for(int i = 0; i < 10000000; ++i) {
memset(dest, 0, sizeof(dest));
snprintf(dest, sizeof(dest), "%s", src);
}
return 0;
}
2. Compile three files respectively:
david@u1110-hp:~/wrk/tmp/cstring$ gcc -std=c99 -o test_memcpy test_memcpy.c
david@u1110-hp:~/wrk/tmp/cstring$ gcc -std=c99 -o test_strncpy test_strncpy.c
david@u1110-hp:~/wrk/tmp/cstring$ gcc -std=c99 -o test_snprintf test_snprintf.c
3. Comparison of consumption time of different functions without optimization:
david@u1110-hp:~/wrk/tmp/cstring$ time ./test_strncpy
real 0m16.472s
user 0m16.309s
sys 0m0.036s
david@u1110-hp:~/wrk/tmp/cstring$ time ./test_snprintf
real 0m6.106s
user 0m6.100s
sys 0m0.000s
david@u1110-hp:~/wrk/tmp/cstring$ time ./test_memcpy
real 0m4.179s
user 0m4.144s
sys 0m0.000s
david@u1110-hp:~/wrk/tmp/cstring$
As you can see from the above results, without any optimization, the performance difference between memcpy() and strncpy() is 4 times, and the performance difference between snprintf() and strncpy() is about 2.5 times.
4. Comparison of consumption time of different functions under O3 optimization:
david@u1110-hp:~/wrk/tmp/cstring$ gcc -std=c99 -O3 -o test_snprintf test_snprintf.c
david@u1110-hp:~/wrk/tmp/cstring$ gcc -std=c99 -O3 -o test_strncpy test_strncpy.c
david@u1110-hp:~/wrk/tmp/cstring$ gcc -std=c99 -O3 -o test_memcpy test_memcpy.c
david@u1110-hp:~/wrk/tmp/cstring$
david@u1110-hp:~/wrk/tmp/cstring$ time ./test_strncpy
real 0m16.178s
user 0m16.161s
sys 0m0.000s
david@u1110-hp:~/wrk/tmp/cstring$ time ./test_snprintf
real 0m6.242s
user 0m6.032s
sys 0m0.056s
david@u1110-hp:~/wrk/tmp/cstring$ time ./test_memcpy
real 0m3.567s
user 0m3.436s
sys 0m0.012s
david@u1110-hp:~/wrk/tmp/cstring$
It can be seen from the above results that after O3 optimization, the performance difference between memcpy() and strncpy() is nearly 5 times, and the performance difference between snprintf() and strncpy() is basically unchanged about 2.5 times.
5. Conclusion of performance comparison:
Never use strncpy() when you need to use a string copy function, always use snprintf() instead, and memcpy() is a better implementation.
Strlen +memcpy is also the implementation of the Linux kernel.
6. Serendipity conclusion:
Change the memset() in the above three files to use bzero() for array zeroing.
Using O3 for optimization, the time of the three functions is as follows:
david@u1110-hp:~/wrk/tmp/cstring$ time ./test_strncpy
real 0m14.395s
user 0m13.929s
sys 0m0.092s
david@u1110-hp:~/wrk/tmp/cstring$ time ./test_snprintf
real 0m3.785s
user 0m3.772s
sys 0m0.000s
david@u1110-hp:~/wrk/tmp/cstring$ time ./test_memcpy
real 0m1.241s
user 0m1.236s
sys 0m0.004s
david@u1110-hp:~/wrk/tmp/cstring$
Conclusion: simply changing the zeroing function results in a performance difference of about 12 times between memcpy() and strncpy(), and about 4 times between snprintf() and strncpy().
Bzero () is far more efficient than memset() for zeroing operations.