手間をかけてデバッグしたロジックを、あっさり捨てて作り替える
メモリ上のデータ量が多くなるのがわかっているシステムがあります。
メモリ上のデータから全件検索をしていると、たとえメモリ上とはいえ検索回数が多いと、処理時間がもったいないだろうなと思いました。
検索の回数を減らすのは難しいので、検索対象の件数を減らすためにインデックスを用意しようと思いつきました。
データは項目A、項目Bを並べ替えの基準として並べ替えられています。
作成しようと思いついたインデックスは、項目Aの値ABCに関係する値が、配列の添字0~3に入っている、項目Aの値DEFに関係する値が、配列の添字4~6に入っている、という形式です。
検索対象のデータ
添字 | 項目A | 項目B | 項目C |
---|---|---|---|
0 | 値ABC | 値001 | 値X01 |
1 | 値ABC | 値002 | 値X02 |
2 | 値ABC | 値003 | 値X03 |
3 | 値ABC | 値004 | 値X04 |
4 | 値DEF | 値101 | 値Y01 |
5 | 値DEF | 値102 | 値Y02 |
6 | 値DEF | 値103 | 値Y02 |
作成するインデックス
項目A | 添字の開始 | 添字の終了 |
---|---|---|
値ABC | 0 | 2 |
値DEF | 4 | 6 |
項目Aさえ決まれば、検索の範囲が全件から少なくなります。
データは、項目A、項目Bを並べ替えの基準で並べ替えられているので、添字の開始から終了まで順番に検索をしていけば、検索が終わります。
このインデックスを作成するロジックを、手間取りましたが実装しました。
項目が増えて順番に検索できない
このデータに項目Dが増えました。
検索対象のデータ
添字 | 項目A | 項目B | 項目C | 項目D |
---|---|---|---|---|
0 | 値ABC | 値001 | 値X01 | 値OPQ |
1 | 値ABC | 値002 | 値X02 | 値RST |
2 | 値ABC | 値003 | 値X03 | 値OPQ |
3 | 値ABC | 値004 | 値X04 | 値RST |
4 | 値DEF | 値101 | 値Y01 | 値OPQ |
5 | 値DEF | 値102 | 値Y02 | 値OPQ |
6 | 値DEF | 値103 | 値Y02 | 値RST |
項目Dを決めて検索を行いたいのですが、項目Dで並べ替えてはいません。
先ほどと同様に順番に検索するために、項目Dを基準に並べ替えてもいいのですが、検索するときには並べ替えたデータを保持していなければなりません。
検索をするたびに並べ替えるか、並べ替えの基準毎にデータを保持していなければならなくなります。
検索をするたびに並び替えるのは、並び替えで時間が使われて、全件検索しないようにして処理時間を短くしようとする目的に対して、本末転倒です。
並び替えの基準毎にデータを保持するのも、2重になぜデータを保持しているのかと、後から疑問に思いそうです。
ここで、配列をforeach文の引数とすればいいのだと思いつき、インデックスを作成しました。
作成するインデックス
項目D | 添字の配列 |
---|---|
値OPQ | 0,2,4,5 |
値RST | 1,3,6 |
インデックスの構造を変えたおかげで、項目Dさえ決まれば、検索ができるようになりました。
ここまでできると、項目Aを決めて検索するときも、同様にした方が統一されますし、開始と終了をfor文で指定しなくても済み、よりソースコードが短くなります。
手間をかけた割には後から思いついたロジックによって、捨てる結果となりました。
何度も書いていますが、結果を見ると最初から思いつきたいと思っています。
最初のロジックを思いついて、さらに良いロジックを思いついたのだから、よかったのだと思うようにしています。