最終更新日 2025年11月15日
■この記事の概要
この記事では、C言語で自作したstrcpy関数が標準関数と比較して5~6倍遅いことを実験を通じて解説し、標準関数の利用を推奨しています。
効率的なプログラミングのために、標準ライブラリを使用する重要性を紹介しています。
■既にある標準関数を実務で自作してはいけない
と別の投稿でも書きましたが
どのくらい処理速度が違うのか
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;
}■自作関数と標準関数の速度比較
#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