HDL で使われている文字列連結

HSP Document Library のソースを読んでみました。

hdl.hsp(バージョン 1.0 ) 1234 行目、 1305 行目と 1446 行目あたりで以下のように文字列の連結を行っていました。

tmp = "" ; accelerator ▽
repeat count
    ( 略 )
    tmp += ( 略 )
    if 1000000\(cnt+1)=0 : buf += tmp:tmp="" ; accelerator
    sql_next
loop
buf += tmp ; accelerator △

これって tmp という変数を使わずに直接 buf に連結しても多分大丈夫だと思うんですが、こうした方が高速なのでしょう。文字列を連結するときには先頭から文字列の終端を探すことになるので、長い文字列だと時間がかかります。連結する文字列をまとめてから連結することで、長い文字列に連結する回数が減って高速になる、ということです。

実験1

本当に速くなるのか試しに実験。

コード

#uselib "winmm.dll"
#cfunc timeGetTime "timeGetTime"

#const trial_times 2000

    proc = *a, *b
    repeat 5, 1
        trial_strlen = cnt * cnt * cnt * 1000
        mes strf("文字列長(%dbytes)の場合:", trial_strlen)
        foreach proc
            sdim buf, trial_strlen + 1
            memset buf, 'a', trial_strlen
            time = timeGetTime()
            gosub proc.cnt
            time = timeGetTime() - time
            mes strf(" %c : ", 'a'+cnt) + strf( "%d[msec]", time )
            await
        loop
        mes
    loop
    stop

*a
    repeat trial_times
        buf += "sample string"
    loop
    return

*b
    tmp = ""
    repeat trial_times
        tmp += "sample string"
        if 1000000\(cnt+1)=0 : buf += tmp:tmp=""
    loop
    buf += tmp
    return

結果

文字列長(1000bytes)の場合:
 a : 35[msec]
 b : 6[msec]

文字列長(8000bytes)の場合:
 a : 62[msec]
 b : 6[msec]

文字列長(27000bytes)の場合:
 a : 125[msec]
 b : 9[msec]

文字列長(64000bytes)の場合:
 a : 215[msec]
 b : 10[msec]

文字列長(125000bytes)の場合:
 a : 329[msec]
 b : 14[msec]

なかなか速くなっているようで驚き。

実験2

HSP3のスクリプトを垂れ流すブログ: 高速な文字列の結合(連結) のスクリプトに以下を追加して試してみました。

コード

    mes "\ntmp使用版計測開始……"
    string = ""
    tmp = ""
    time_start = timeGetTime()
    repeat TRIAL_TIME
        tmp += "sample string\n"
        if 1000000\(cnt+1)=0 : string += tmp:tmp=""
    loop
    string += tmp
    time(3) = timeGetTime() - time_start
    mes strf("tmpを使用:%d[ms]", time(3))
    mes "tmp使用版計測終了。"

結果

独自命令版計測中……
独自命令を使用:88[ms]
独自命令版計測終了。

+=使用版計測開始……
標準の+=を使用:1020[ms]
+=使用版計測終了。

noteadd使用版計測開始……
noteaddを使用:3306[ms]
noteadd使用版計測終了。

tmp使用版計測開始……
tmpを使用:123[ms]
tmp使用版計測終了。

poke を使うのよりやや遅いくらいです。 += を使うのでも工夫すれば速くなるのですね。

計測した環境は Windows XP Home SP2 / Pentium 4 CPU 2.40GHz / 512 MB RAM です。

参考

インフォメーション

公開日時
2008年1月26日 午後2時31分30秒
最終更新日時
2008年1月26日 午後3時36分14秒
カテゴリ
HSP