プログラミング講座(17) チューニング

では、どこが遅いのか当りをつけて直してみましょう。単語帳プログラムは入力ファイルを読み込むうちにだんだんと遅くなっていましたね。1行読むたびにその行から単語を切り出して、単語帳に登録していました。どうやらその登録の処理がだんだんと重くなっているようです。以下のリストはそのプログラムの部分の抜粋です。
【リスト6 InsertWordListサブルーチン】
97 ‘サブルーチン InsertWordList (単語帳に単語を登録する)
98 ‘input: word (単語)
99 ‘input: wordlist[] (単語帳: 単語)
100 ‘input: lnolist[] (単語帳: 行番号)
101 ‘input: wno (登録した単語数)
102 ‘work: i, j (単語帳の引数)
103 ‘output: wordlist[] (単語帳: 単語)
104 ‘output: lnolist[] (単語帳: 行番号)
105 ‘output: wno (登録した単語数)
106 Sub InsertWordList
107  For i = 1 to wno
108   CompareWord()
109   If (cwresult = “<") Then
110    For j = wno to i step -1
111     wordlist[j + 1] = wordlist[j]
112     lnolist[j + 1] = lnolist[j]
113    EndFor
114    wordlist[i] = word
115    lnolist[i] = lno
116    Goto exitiwl
117   EndIf
118  EndFor  
119  wordlist[wno + 1] = word
120  lnolist[wno + 1] = lno
121 exitiwl:
122  wno = wno + 1
123 EndSub
ここでは何をしているかというと、切り出した単語を wordlist[] という配列に登録しているのですが、アルファベット順になるように挿入すべき場所が見つかったら、それ以降の単語リストを1つ分すべてコピーしています。このコピーは単語の数が多くなるほどコピー回数が増えて行くので、ここが遅い原因だろうと目星を付けました。
Photo
【図14 配列構造】
そこで、この配列をコピーしないで済むような、ポインタを使った構造に変えてみることにします。
Photo_2
【図15 ポインタ構造】
その結果できたのがWordList v0.6で、例によって[発行]の機能でアップロードしました。プログラムIDはHBQ757です。「プログラミング講座(16)」でも述べたとおり、
30 ‘ line = File.ReadLine(filename, lno)
57 ‘ line = File.ReadLine(filename, lno)
の2行はコメントになっているのでシングルクォートを消して元に戻してください。そして、
11 ‘改善後のポインタ構造を使用するか?
12 improved = “True”
の12行目の変数 improved が “True” に設定してありますが、この場合はチューニング後のポインタを使った(コピーを行わない)サブルーチンを呼び出します。これを “False” に変更すると、チューニング前の配列を使った(コピーを行う)サブルーチンを呼び出します。
また、v0.5では入力ファイルはプログラム中で WordList03.sb を指定していましたが、v0.6ではコマンドラインから入力するように変更しました。
File name?
と出るので、ここで WordList03.sb をタイプしてEnterキーを押します。v0.6の12行目の変数を “True” と “False” で実行した結果は、以下の通りです。環境によって数値は変化すると思いますが、配列のコピーを止めることで、実用的なスピードになったと思います。
改善前のタイム 0:0:56
改善後のタイム 0:0:4
(つづく)

コメントを残す