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 関数にかかる時間が増えていく。そんな感じだ。
アカウントを作成 して、もっと沢山の記事を読みませんか?
この記事が気に入ったら ことりと さんを応援しませんか?
メッセージを添えてチップを送ることができます。
この記事にコメントをしてみませんか?