QUICKDBを書き直して劇的に高速化

QUICKDBを大幅に書き直してKAKEIZU::getmarriageとgetcarddataでレコード全体を取り出すように修正したところ,データベースのロード処理が劇的に高速化した.これまではかなりの時間待たなくてはならなかったところ,ほとんど瞬時に完了するようになった!1万点を超えるサンプルをそこそこの時間で開けるようにしたいのだが,まだまだ手が届かない.ボトルネックになっているのはセグメント検定だが,それ以外では,ClearTableにかなりの時間を浪費している.

いや,その前にステージ7リンクの検証,ルックアップテーブルの生成にかなりの時間が掛かっている.ここでやっているのは,①CheckDataLink,②MakingLookUp,③NameSortだけだ.⇒どうも重いのは,③NameSortのようだ.改善の余地はあるだろうか?

53直系血族サンプルで,CheckDataLinkの所要時間は1.6秒,MakingLookUpは0秒,NameSortは344msだ.CheckDataLinkはZELファイルを読み込んだ場合ではパスしてもよい.Collatz4000X.ZELでは,NameSortで14.3秒掛かっている.⇒NameSortはlookup.tableを直接操作しているが,ループの中で前詰めを実行しているので,余分な手間が掛かっているのではないだろうか?書き直してみよう.

どうも,大した効果は得られなかった.13.953秒なので300msくらいしか短縮されなかった.いや,そもそも,どちらのサンプルもlookupには穴が空いていないので,前詰めによる時間浪費はミニマムなものでしかない.とりあえず,時間短縮するならNameSortをやらないようにするしかないだろう.これは仕様の問題であり,そう決めればよいというだけの話だ.⇒対処した.

ClearTableは後から見ることにして,三極検定,中でもセグメント検定の効率化が可能かどうかを見てみよう.⇒checkをオンにしただけなのだが,どこか壊してしまったのだろうか?動作がおかしくなってしまった.セグメント検定用のツールが壊れている.それにしても,checkを入れただけで副作用が発生するというのは考えづらい.⇒関数の実行に掛かる時間を測定・表示するために挿入したコードが誤動作していたようだ.GetTickCountで取り出した値はULONGLONGで,printfの書式の説明では%dでlong longを表示できるように書かれていたのだが… 誤動作を避けるため,引数でulong(xxx)で型変換するようにして収まった.

セグメント検定の実行ルーチンであるHorizontalSegmentは小さい方のサンプルでも600msくらい掛かっているが,その中から呼び出しているCheckMaximalSegmentが一回の呼び出しで200ms掛かり,それを3回実行しているので,HorizontalSegmentの実行時間のほとんどはCheckMaximalSegmentが費やしていることになる.従って,CheckMaximalSegmentの処理時間を短縮できれば,それだけHorizontalSegmentも軽くなるということになる.

しかし,その前に3回も実行する必要があるのかどうかもチェックしておく必要があるだろう.⇒3回を入口検査の1回だけに削減した.これだけでもかなり高速化した.トイレに入っている間に大きい方のサンプルが描画できるところまで来た.ここまで来ればそこそこ実用になる.大きいサンプルではHorizontalSegmentを1回実行するのに2.6秒くらい掛かっている.このうち,CheckMaximalSegmentが2.3~2.4秒で大半を占めている.CheckMaximalSegmentはもう少しダイエット可能だと思われるが,その前に系統並び替えに入ってから三極検定に移るまでに掛かっている時間コストを調べておこう.

系統並び替え全体では,サンプルA(1931点)で14秒,サンプルB(12243点)で316秒≒5分だ.まず,バックアップを取ってから始めよう.TOPOLOGY::ClearTableではlookupを使っていない.これはかなり不利だと思う.書き直してみよう.⇒57秒掛かった.修正前の時間を測っていないので,改善しているのかどうかは分からないが,ClearTableだけで1分というのはやはりかかり過ぎのような気がする.なぜだろう?結婚ではlookupを使わないことにしたのだが,かなり疎なテーブルになっている.結婚リンク数が1393のところ,テーブルは3578で3倍近くある.

確かに飛び番になっている.復活させるのはそれほど手は掛からないと思うが…サンプルBでは逆のことが起こっている.PDB,MDBとlookupのカウントが完全に同じだ.つまり,テーブルは最初から密に詰まっている.おそらく,これは以前保存するとき,基準ソートされた状態で保存していたのだろう.基準ソートするとテーブルは完全に前詰めされた状態になる.現在もそういう仕様になっているかどうかは分からない…いずれにせよ,サンプルBに関してはlookupを使っても効果はまったく出ないということになる.LINKTABLE:CheckIfMargValidという検査ルーチンはNOCHECKDATALINKで止めておこう.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA