pokeとmemexpandを利用した文字列の結合(連結)。
HSP標準の+=やnoteaddよりも高速に実行することができます。
このモジュール最大の利点は、memexpandによる変数の自動拡張にあります。(X)HTMLコンバータのように出力結果の大きさが分からないスクリプトで重宝するでしょう。
サンプルスクリプトのように決まった文字列を結合(連結)し続ける場合(リフレイン)、この命令よりもFujiさんのブログの記事で紹介されている方法の方がより高速です。
先日の(X)HTML変換スクリプトの他、開発wikiの置換モジュールでも似たような処理が使われています。#module
#const EXPAND_SIZE 1024
// 文字列の初期値を設定する
#deffunc set_string str str_to_set
string_length = strlen(str_to_set)
; string_size = EXPAND_SIZE * (1 + string_length / EXPAND_SIZE)
string_size = 64 // 測定のために公平化
sdim string, string_size
poke string, 0, str_to_set
return
// 文字列を返す
#deffunc get_string var target
target = string
return
// 文字列の長さを返す
#defcfunc get_string_length
return string_length
// 文字列を連結する
#deffunc add_string str str_to_add
len = strlen(str_to_add)
if string_size <= string_length + len {
string_size += EXPAND_SIZE
memexpand string, string_size
}
poke string, string_length, str_to_add
string_length += len
return
#global
#const TRIAL_TIME 10000
#uselib "winmm.dll"
#cfunc timeGetTime "timeGetTime"
mes "充分なサイズを確保せずに文字列の結合(連結)を実行。"
mes "独自命令版計測中……"
set_string ""
time_start = timeGetTime()
repeat TRIAL_TIME
add_string "sample string\n"
loop
time(0) = timeGetTime() - time_start
mes strf("独自命令を使用:%d[ms]", time(0))
mes "独自命令版計測終了。\n"
mes "+=使用版計測開始……"
string = ""
time_start = timeGetTime()
repeat TRIAL_TIME
string += "sample string\n"
loop
time(1) = timeGetTime() - time_start
mes strf("標準の+=を使用:%d[ms]", time(1))
mes "+=使用版計測終了。\n"
mes "noteadd使用版計測開始……"
notesel string
sdim string, 64
time_start = timeGetTime()
repeat TRIAL_TIME
noteadd "sample string"
loop
time(2) = timeGetTime() - time_start
mes strf("noteaddを使用:%d[ms]", time(2))
mes "noteadd使用版計測終了。"
stop
2007年12月16日日曜日
高速な文字列の結合(連結)
登録:
コメントの投稿 (Atom)
2 件のコメント:
加算じゃなくて連結って言ったほうがいいと思う。
ご指摘ありがとうございます。
HSP3のヘルプを確認しましたら、結合と表記されていましたのでそちらに変更したいと思います。連結も併記しておきます。
コメントを投稿