と別の投稿でも書きましたが
どのくらい処理速度が違うのか
mem系関数に続いてsrc系関数を
自作関数と標準関数で比較してみました。
■自作strcmp
int 自作strcmp(const char* s1, const char* s2) {
while (*s1 && (*s1 == *s2)) {
s1++;
s2++;
}
return *s1 - *s2;
}
■自作strcpy
char *自作strcpy(char* dest, const char* src) {
while (*src != '\0') {
*dest = *src;
dest++;
src++;
}
*dest = '\0';
return dest;
}
■自作strlen
size_t 自作strlen(const char *s) {
size_t len = 0;
while (*s != '\0') {
len++;
s++;
}
return len;
}
■自作strncmp
int 自作strncmp(const char* str1, const char* str2, size_t n)
{
for (size_t i = 0; i < n; i++){
if (str1[i] != str2[i]){
return str1[i] - str2[i];
}
if (str1[i] == '\0'){
return 0;
}
}
return 0;
}
■自作strncpy
char* 自作strncpy(char* dest, const char* src, size_t n) {
char* ret = dest;
while (n > 0 && *src != '\0') {
*dest++ = *src++;
n--;
}
while (n > 0) {
*dest++ = '\0';
n--;
}
return ret;
}
■自作関数vs標準関数
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <assert.h>
int 自作2引数(char *dst,char *src){
自作strcpy(dst,src);
return 自作strcmp(src,dst) ;
}
int 標準2引数(char *dst,char *src){
strcpy(dst,src);
return strcmp(src,dst) ;
}
int 自作3引数(char *dst,char *src){
size_t size = 自作strlen(src)+1;
自作strncpy(dst,src,size) ;
return 自作strncmp(dst,src,size);
}
int 標準3引数(char *dst,char *src){
size_t size = strlen(src)+1;
strncpy(dst,src,size) ;
return strncmp(dst,src,size);
}
typedef int (*関数ポインタ_型)(char *,char *);
static inline void 時間計測(
char *title,
関数ポインタ_型 計測対象関数,
char *dst,
char *src
){
clock_t start = clock();
for(int j = 0;j < 0x10000 ; j++){
const size_t max = strlen(src);
for(size_t i = 0;i < max ; i++){
if(計測対象関数(dst,src+i) != 0){
assert(0);
}
}
}
clock_t end = clock();
printf("%s\t:%.2f 秒\n",title, (double)(end - start) / CLOCKS_PER_SEC);
//printf("%s\t%8ld clock\n",title, end - start);
}
char *src =
"Jugemu Jugemu,"
"Gokō no Surikire,"
"Kaijarisuigyo no Suigyōmatsu,"
"Ungyōmatsu,"
"Fūraimatsu,"
"Kuunerutokoro ni Sumutokoro,"
"Yaburakōji no Burakōji,"
"Paipo Paipo,"
"Paipo no Shūringan,"
"Shūringan no Gūrindai,"
"Gūrindai no Ponpokopī no Ponpokona no Chōkyūmei,"
"Chōkyūmei no Chōsuke";
static char dst1[BUFSIZ];
static char dst2[BUFSIZ];
static char dst3[BUFSIZ];
static char dst4[BUFSIZ];
int main(void){
時間計測("標準2引数",標準2引数,dst2,src);
時間計測("標準3引数",標準3引数,dst4,src);
時間計測("自作2引数",自作2引数,dst1,src);
時間計測("自作3引数",自作3引数,dst3,src);
printf("dst1[0]=%c\n",dst1[0]);
printf("dst2[0]=%c\n",dst2[0]);
printf("dst3[0]=%c\n",dst3[0]);
printf("dst4[0]=%c\n",dst4[0]);
}
やっている事は
“Jugemu Jugemu,~~”の長い文字列を
一文字づつずらしながら
外部変数の配列にコピーして、
コピー元と比較しています。
ご自分の環境にコピペしてコンパイル&実行してみて下さい。
■実験結果
+ gcc -Wall -Wextra vs.c
+ ./a.out
標準2引数 :0.47 秒
標準3引数 :0.83 秒
自作2引数 :10.77 秒
自作3引数 :19.02 秒
dst1[0]=e
dst2[0]=e
dst3[0]=e
dst4[0]=e
+ gcc -Wall -Wextra vs.c -O
+ ./a.out
標準2引数 :0.67 秒
標準3引数 :1.14 秒
自作2引数 :3.98 秒
自作3引数 :6.20 秒
dst1[0]=e
dst2[0]=e
dst3[0]=e
dst4[0]=e
筆者の環境下では
最適化ありで1.14秒対6.20秒。
毎回結果が微妙に変わりますが、
だいたい自作関数は標準関数より
5~6倍くらい遅いようです。
自分ならもっと高速な自作関数を書けると
お考えの方は是非自作関数を書き換えて実験してみて下さい。