結構前に構築しようとしたサイトを作っていますが、これまで作ったソースを流用している中で、どうもページの表示が遅い部分がある。
なんでだろう。って計測してみた。
<?php /** * データベースから取得した配列をタグ情報を配列化して組み直す関数 */ public function findAllContents() { // 時間計測開始 $time_start = microtime(true); // パラメータを取得 $params = $this->getPrams(); // データベースからデータを取得 $data = $this->find('all', $params); // 時間確認 // 結果(平均) -> 0.017928123474121 $timeFindEnd = microtime(true) - $time_start; $this->log('find end :' . $timeFindEnd); // 配列を組み直し $resutl = $this->reInsertArray($data); // 時間計測 // 結果(平均) -> 5.6694331169128 (!!?) $timereInsert = microtime(true) - $time_start; $this->log('reInsert end :' . $timereInsert); // 値を返却 return $resutl; }
あぁー、おせぇ、合計6秒だと。。。
しかも、ネックはここでしょう
// 配列を組み直し
$resutl = $this->reInsertArray($data);
このメソッドは、データベースからデータを取得した際に、フォーマットが['Model Name'] => array(...)ってなるので、当時はmergeするのにすごくめんどくさかった。
なので、再帰的に配列の下層を取得するarray_walk_recursive()を使ったってのが、前の記事aipacommander.hatenablog.jp
しょうがないのかな? と、思いつつも、さすがに6病はヤバイと思ったので、これを利用しているメソッドを、今の俺ならどこまでいけるかなと思って、触ってみる。
ちなみにDBから取得したデータの形はこうだ
[0] => Array ( [ArrayA] => Array ( [id] => 15 ) [ArrayB] => Array ( [id] => 2 ) [0] => Array ( [tag_name] => test ) )
かなり省略しているが、こんな感じだ。
上にも書いたが当時の自分はこの配列の形が嫌いだった。すぐにアクセスは出来ないし、取得するモデルで名前が変わる。汎用を求めたかったので、一番下層の配列だけ取得できるように、その間のことについては考えないプログラムを組みたかったのだ。
だけど、よくよく考えたら、すでに形が決まっているのであれば、間の指定の仕方も決まってくる。
と、いうことでこんな感じにしてみる。
/** * データベースから取得した配列をタグ情報を配列化して組み直す関数 */ public function reInsertArray($data) { $result_array = array(); // 番号の配列 -> 連想配列のフォーマットで配列を組み直す foreach($data as $k => $v) { $tmp_array_save = array(); // それぞれ真ん中の配列を見やすく $arrayA = $v['ArrayA']; $arrayB = $v['ArrayB']; // group_concatの結果がこうなる。。。これはどうにかならないかな? $arrayC = $v['0']; // 配列をマージ $tmp_array_save = array_merge($arrayA, $arrayB, $arrayC); // 返却する配列を追加 array_push($result_array, $tmp_array_save); } // 値を返す return $result_array; }
めっちゃシンプルになった!
時間を測ってみる。
find end :0.018357038497925
reInsert end :1.0395188331604
ほげぇえええええええええええええええええええええええ(^q^)
5秒縮んだ。すげぇ!
何故、array_walk_recursive()が遅いのはまではわかりませんが、Simple is bestですね。
組み直してよかったわ。
汎用性は無くなったけど、そこは間をメソッド化して、複数用意してもいいと思う。あとは、モデルを引数(または配列)で受け取るとかね。
以上!