字串拷貝函式memcpy和strncpy以及snprintf 的效能比較
以下是對字串拷貝函式memcpy和strncpy以及snprintf它們之間的效能進行了比較,需要的朋友可以過來參考下
問題:
- 函式memcpy(dest, src, sizeof(dest))、strncpy(dest, src, sizeof(dest))和snprintf(dest, sizeof(dest), “%s”, src)都可以將src字串中的內容拷貝到dest字串中。
- 哪一種方式效率最高呢?就是說,哪種方式效能最好呢?
解決辦法:
建立三個檔案test_memcpy.c,test_strncpy.c和test_snprintf.c:
檔案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;
}
檔案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;
}
檔案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;
}
分別編譯三個檔案:
[email protected]-hp:~/wrk/tmp/cstring$ gcc -std=c99 -o test_memcpy test_memcpy.c
[email protected]-hp:~/wrk/tmp/cstring$ gcc -std=c99 -o test_strncpy test_strncpy.c
[email protected]-hp:~/wrk/tmp/cstring$ gcc -std=c99 -o test_snprintf test_snprintf.c
沒有優化的情況下不同函式消耗時間對比:
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
從上面執行結果可以看出:沒有任何優化的情況下,memcpy()和strncpy()效能相差4倍,snprintf()和strncpy()效能相差約2.5倍。
採用O3優化情況下不同函式消耗時間對比:
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
從上面執行結果可以看出:採用O3優化後,memcpy()和strncpy()效能相差近5倍,snprintf()和strncpy()效能相差基本不變約2.5倍。
效能對比結論:
- 在需要用到字串拷貝函式的時候,永遠不要使用strncpy(),無論什麼時候都用snprintf()來代替,而memcpy()是效能更好的實現方式。
- strlen+memcpy也是linux核心的實現方式。
意外收穫結論:
將上述三個檔案中的memset()改為用bzero()來實現陣列的清零操作。
使用O3來進行優化,三個函式的耗時時間如下:
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
結論:
- 僅僅換了一個清零函式,使得memcpy()和strncpy()的效能差別達到約12倍,而snprintf()和strncpy()的效能差別也達到約4倍。
- 就清零操作來說,bzero()遠比memset()更高效。
相關推薦
字串拷貝函式memcpy和strncpy以及snprintf 的效能比較
以下是對字串拷貝函式memcpy和strncpy以及snprintf它們之間的效能進行了比較,需要的朋友可以過來參考下 問題: 函式memcpy(dest, src, sizeof(dest))、strncpy(dest, src, siz
strncpy字串拷貝函式
摘自linux核心4.11.1 原始碼string.c linux/lib/string.c Copyright (C) 1991, 1992 Linus Torvalds 標頭檔案:#include <string.h> 作用:將源字串src複製count個
拷貝函式memcpy
memcpy 記憶體拷貝函式,本篇就是個筆記而已。。。 拷貝陣列 例 #include<stdio.h> #include<string.h> int main() {int a[3]={1,2,3}; int b[3],i; memcpy(b,a,sizeo
如何自己實現字串拷貝函式
一般寫法: char *my_strcpy(char *dst,const char *src) { assert(dst != NULL); assert(src != NULL); char *ret = dst; while((* dst++ = * src++) != '\0'
記憶體拷貝函式 memcpy
windows下實現: void* __cdecl memcpy(void* dst,const void* src,size_t count) { void*ret=dst; #if defined(_M_MRX000)||defined(_M_ALPHA)||defined(_M_PP
javascript中bind()函式實現和應用以及多次bind的結果和引數位置的思考
改變物件方法裡this的值var ob = { name: 'joe', getName: function () { alert(this.name); } }; // 改變getName方法裡原本的this物件為新物件{name: 'haha'} var app = ob.getName.bi
oracle獲取字串長度函式length()和hengthb()
oracle獲取字串長度函式length()和hengthb()lengthb(string)計算string所佔的位元組長度:返回字串的長度,單位是位元組length(string)計算string所佔的字元長度:返回字串的長度,單位是字元 對於單位元組字元,LENGTHB和LENGTH是一樣的.如可以用l
C++虛擬函式宣告和定義以及g++編譯遇到的一些問題
遇到了一些麻煩的,記錄下來作為教訓….. 1. 虛擬函式的宣告和定義 具體關於虛擬函式的知識不做多講,我在定義一個抽象類時,忘了將一個虛擬函式宣告為 純虛擬函式,又沒有對其定義, 導致編譯報錯時報錯如下: undefined reference to
記憶體拷貝函式memcpy
memcpy memcpy是C/C++記憶體拷貝函式,函式原型void*memcpy(void *dest, const void *src, size_t n);功能是從源src所指的記憶體地址的起始位置開始拷貝n個位元組到目標dest所指的記憶體地址的起始位置中。 【m
C/c++中記憶體拷貝函式memcpy詳解
原型:void*memcpy(void*dest, const void*src,unsigned int count); 功能:由src所指記憶體區域複製count個位元組到dest所指記憶體區域。 說明:src和dest所指記憶體區域不能重疊,函式返回指向des
C++之 字串拷貝函式(面試題目)
1.已知strcpy 函式的原型是:char *strcpy(char *strDest, const char *strSrc);其中strDest 是目的字串,strSrc 是源字串。不呼叫C++/C 的字串庫函式,請編寫函式 strcpy答案:c程式碼 char *strcpy(char *strDe
C語言字串擷取函式strtok和strtok_r
在看原始碼的時候需要將一段並排的IPs轉化成為一系列的IP,將"10.0.0.1;10.0.0.2;10.0.0.3;10.0.0.4;10.0.0.5"轉換成為單獨的"10.0.0.1
考慮了記憶體重疊的字串拷貝函式strcpy
考慮了記憶體重疊的字串複製函式 char * strcpy(char *dest, char *src) { char *d = dest; //backup input char *s = src; int count = 0; assert(dest); //非空指
JavaScript——for和for in 的效能比較與for迴圈的優化方案
在JavaScript中,我們遍歷陣列的時候經常需要用到for和for in。今天來比較一下這兩個遍歷方法的效能,並提供優化方案。 1.for 和for in的效能比較 我們都知道,for 和for in的時間複雜度一樣,但是其效能有些許差距。具體有多大差距呢,下面我們來
pandas中apply和transform方法的效能比較
1. apply與transform 首先講一下apply() 與transform()的相同點與不同點 相同點: 都能針對dataframe完成特徵的計算,並且常常與groupby()方法一起使用。 不同點: apply()裡面可以跟自定義的函式,包括簡單的求和函式以及複雜的特徵間的差值函式等(注:appl
V4L2採集+編碼壓縮(M-JPEG和H.264壓縮效能比較)
Linux下,一般的普通USB攝像頭V4L2視訊採集有兩種方式:V4L2_PIX_FMT_MJPEG和V4L2_PIX_FMT_YUYV。 V4L2_PIX_FMT_MJPEG採集方式得到的是經過M
RelativeLayout和LinearLayout效能比較 相對佈局和線性佈局的效能比較
看到幾篇關於RelativeLayout和LinearLayout效能分析的部落格,寫的相當不錯,這裡在大神的基礎上,增加了部分內容 RelativeLayout和LinearLayout是Android中常用的佈局,兩者的使用會極大的影響程式生成每一幀的效能,因此,正確的使用它們是提升
lambda表示式foreach和普通for迴圈效能比較
java 8的新特性之一就是lambda表示式,其中lambda表示式的foreach迴圈最為引人注目,現比較下lambda表示式foreach和普通for迴圈的效能測試。程式碼如下: public static void main(String[] args){ List
Hive over HBase和Hive over HDFS效能比較分析
http://superlxw1234.iteye.com/blog/2008274環境配置:hadoop-2.0.0-cdh4.3.0 (4 nodes, 24G mem/node)hbase-0.94.6-cdh4.3.0 (4 nodes,maxHeapMB=9973/
Java直接記憶體和堆記憶體的效能比較
在JDK 1.4中新加入了NIO(New Input/Output)類,引入了一種基於通道(Channel)與緩衝區(Buffer)的I/O方式, 它可以使用Native函式庫直接分配堆外記憶體,然後通過一個儲存在Java堆裡面的DirectByteBuffer物件作為