[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[WitchTech 00712] Re: 文字列を数値に変換するには?



 こんにちは、近藤です。

Shigeki 'anmitsu' Yamamotoさんの<200102141620.BAA05945@cds.ne.jp>から
>遅いというのの根拠が分かりません。。。
>関数呼び出しののオーバヘッド以外に遅くなる理由があるのでしょうか?

 内部処理の問題なのですが、単純に 1,024bytes の文字列を 
1,024 回後ろに追加する処理を書いてみると分かりやすいと思いま
す。

# マシンが速い場合には回数をもっと多くすると分かります。

 strcat() で追加していく場合、毎回 src の最後をサーチする処
理(*1)が入りますが、 sprintf() はうまく使うことで(*2)これを
避けられます。

-----
*1) strcat() 内部の処理 - from FreeBSD 4.2-STABLE source
char *
strcat(s, append)
    register char *s;
    register const char *append;
{
    char *save = s;

    for (; *s; ++s);
    while ((*s++ = *append++));
    return(save);
}

 これにより、毎回 s の末尾を探す処理が入るため非常に無駄が
増えてしまいます。

-----
*2) sprintf() の有効利用
char* p = buf;  /* buf には十分なバッファがあるとする */

p += sprintf(p, "%s", append1);
p += sprintf(p, "%s", append2);
p += sprintf(p, "%s", append3);

 これにより、常に buf に格納されているバッファの末端を p が
指す事となります。

 追加する文字列が短く、最終的にも文字列が十分に短い場合には 
strcpy()/strcat() を利用したほうが高速です。
 逆に、 sprintf() のソースコードを追いかけるとすぐにわかり
ますが、 printf() 系は基本コストが高いため、ある程度扱う文字
列が長かったりしないと優位にはなりません。

# printf("%s", NULL); なんかしてしまうと悲しいことになったり
# することもありますし……。

 ちなみに、 sprintf() で呼び出される vfprintf() はソースが
実に 1282 行も渡っていたりするコードなので、リンクしないで済
むならしない方がバイナリは小さくなりますし。

# vfprintf() を参考にして簡単な sprintf() を作るなどしたほう
# が Witch にはコスト安くていいかも。
# 内部で宣言されている自動変数もかなり多いですし。

-- 
Fuji. / KONDOU, Kazuhiro
site top url : http://www.ancientlibrary.net/
mail address : fuji@ancientlibrary.net


ML Archives