【C言語】
自作のmemcpyは
標準関数の20倍遅かった


パチモノ自作関数を実務で作ってはいけない

と別の投稿でも書きましたが
どのくらい処理速度が違うのか
自作関数と標準関数を比較してみました。

■自作関数vs標準関数

#include    <stdio.h>
#include    <string.h>
#include    <time.h>
#include    <assert.h>
int 自作memcmp(const void *s1, const void *s2, size_t n){
    const   char  *p1 = s1;
    const   char  *p2 = s2;
    for(size_t i = 0; i < n;i++){
        if (p1[i] != p2[i]){
            return  p1[i] - p2[i];
        }
    }
    return (0);
}
void *自作memcpy(void *s1, const void *s2, size_t n){
    char        *p1 = s1;
    const char  *p2 = s2;
    for(size_t i = 0; i < n;i++){
        p1[i] = p2[i];
    }
    return (s1);
}
void *自作memset(void *s, int c, size_t n){
    char       *p = s;
    for(size_t i = 0; i < n;i++){
        p[i] = c;
    }
    return (s);
}
int 自作(void *dst,void *src,size_t size){
    自作memset(src,'Q',size);
    自作memcpy(dst,src,size);
    return  自作memcmp(dst,src,size);
}
int 標準(void *dst,void *src,size_t size){
    memset(src,'Q',size);
    memcpy(dst,src,size);
    return  memcmp(dst,src,size);
}
typedef  int (*関数ポインタ_型)(void *,void *,size_t);
static inline void    時間計測(
    char    *title,
    関数ポインタ_型     計測対象関数,
    char    *dst,
    char    *src
){
    clock_t     start   = clock();
    for(int j = 0;j < 0x100 ; j++){
        for(int i = 0;i < BUFSIZ; i++){   
            if(計測対象関数(dst,src,BUFSIZ) != 0){
                assert(0);
            }
        }
    }    
    clock_t     end     = clock();
    printf("%s\t%8ld clock\n",title, end - start);
}
char    g1buf[BUFSIZ];
char    g2buf[BUFSIZ];
int main(void){
    char    a1buf[BUFSIZ]; 
    char    a2buf[BUFSIZ]; 
    時間計測("自作",自作,g1buf,a1buf);
    時間計測("標準",標準,g2buf,a2buf);
    printf("自作確認=QQ=%c%c\n",g1buf[0],g1buf[BUFSIZ-1]);
    printf("標準確認=QQ=%c%c\n",g2buf[0],g2buf[BUFSIZ-1]);
}

やっている事は
コピー元の自動変数配列を文字Qで埋めて、
コピー先の外部変数配列へ転送し
コピー元とコピー先を比較しています。
最後にコピー先配列の最初と最後に
文字Qが入っている事を確認しています(手抜きの確認)。

ご自分の環境にコピペしてコンパイル&実行してみて下さい。


■実験結果(24対1)

+ gcc -Wall -Wextra vs.c
+ ./a.out
自作    154546875 clock
標準      1250000 clock
自作確認=QQ=QQ
標準確認=QQ=QQ
+ gcc -Wall -Wextra vs.c -O2
+ ./a.out
自作    24703125 clock
標準     1296875 clock
自作確認=QQ=QQ
標準確認=QQ=QQ

筆者の環境下では

最適化ありで24対1
毎回結果が微妙に変わりますが、

だいたい自作関数は標準関数より20倍くらい遅いようです。

ポインタを使えば早くなるとか、
後置演算子++でなくて++前置演算子を使えば早くなるとか
お考えの方は是非自作関数を書き換えて実験してみて下さい。