メイン画像

C言語 - strlen/strcat 関数で長い文字列を扱うと遅くなる

C言語 - strlen/strcat 関数で長い文字列を扱うと遅くなる


strlen 関数は文字列の先頭からNULL文字を探していく。
そのため長い文字列を引数にすると、その分、時間がかかってしまう。

strcat 関数も同様。
第1引数のNULL文字から第2引数の文字列を結合する動きなので、第1引数の文字列が長いと時間がかかる。

本当にそうなのか?

strlen 関数で確かめてみた。

方法は 1KiB と 1MiB の文字列に対して strlen 関数をそれぞれ10万回実行するのにかかった時間を計測する。

結果、1KiB は 0.03 秒だったのに対し 1MiB は 19.61 秒もかかった。
(3回実行した平均時間)

▼ソースコード 1KiB 計測用

char string_1kb[1024+1];
memset(string_1kb, 'A', sizeof(string_1kb) / sizeof(char));
string_1kb[1024] = '\0';

for (i = 0; i < 100000; i++) {
    size_t tmp1 = strlen(string_1kb);
}

▼ソースコード 1MiB 計測用

1MiB の静的メモリは確保できなかったので、malloc() で動的に確保している。

size_t size_1mib = 1048576 + 1;

char *string_1mib = (char *)malloc(size_1mib);
if (string_1mib == NULL) {
    return 1;
}

memset(string_1mib, 'A', size_1mib);
string_1mib[size_1mib-1] = '\0';

for (i = 0; i < 100000; i++) {
    size_t tmp2 = strlen(string_1mib);
}

free(string_1mib);
string_1mib = NULL;

 

過去の話。
とあるプログラムで CSV だったか JSON だったかを生成する処理があった。

その処理では元データをループで回し、各値を strcat 関数で連結していた。

元データの件数が少ないときは問題なかったが、件数が増えるにつれて処理時間がかかるようになり、原因を調査したところ strcat 関数が悪さをしていたことがあった。

イメージ

for (i = 0; i < list_num; i++) {
    strcat(buf, "\"");
    strcat(buf, list[i].data1);
    strcat(buf, "\",\"");
    strcat(buf, list[i].data2);
    strcat(buf, "\",\"");
    strcat(buf, list[i].dataN);
    :
    :
    strcat(buf, "\"\r\n");
}

buf はオーバーフローしないようにメモリー確保済み。

元データの件数によって buf の文字数が増えることで、strcat 関数にかかる時間が増えていく。そんな感じだ。


アカウントを作成 して、もっと沢山の記事を読みませんか?


この記事が気に入ったら ことりと さんを応援しませんか?
メッセージを添えてチップを送ることができます。


この記事にコメントをしてみませんか?


酒とアクアリウムが最近の楽しみ。

おすすめの記事