php 無限分類遞迴 和 無限分類引入 的效能差距

NEKGod發表於2020-09-25

php 無限分類遞迴 和 無限分類引入 的效能差距

      引用方法:
      function generateTree($array){
            //第一步 構造資料
            $items = array();
            foreach($array as $value){
                $items[$value['id']] = $value;
            }
            //第二部 遍歷資料 生成樹狀結構
            $tree = array();
            $level = 0;
            foreach($items as $key => $item){
                if(isset($items[$item['pid']])){
                    $items[$key]['level'] = $level;
                    $items[$item['pid']]['son'][] = &$items[$key];
                }else{
                    $level = 0;
                    $items[$key]['level'] = $level;
                    $tree[] = &$items[$key];
                }
            }
            return $tree;
        }
        輸出程式碼: 
        $array = Db::name('area')->select();
        $arr = $this->generateTree($array);
        $queue = new \SplQueue();
        foreach ($arr as $vo) {
            $vo['level'] = 0;
            $queue->push($vo);
        }
        while (!$queue->isEmpty()) {
            $val = $queue->shift();
            echo str_repeat('-', $val['level']).$val['name'].'
';
            if (!empty($val['son'])) {
                for ($index = count($val['son']) - 1; $index >= 0; $index--) {
                    $val['son'][$index]['level'] = $val['level'] + 1;
                    $queue->unshift($val['son'][$index]);
                }

                continue;
            }
        }
         遞迴方法:
         function getTree($array, $pid =0, $level = 0){
            //宣告靜態陣列,避免遞迴呼叫時,多次宣告導致陣列覆蓋
            static $list = [];
            foreach ($array as $key => $value){
                //第一次遍歷,找到父節點為根節點的節點 也就是pid=0的節點
                if ($value['pid'] == $pid){
                    //父節點為根節點的節點,級別為0,也就是第一級
                    $value['level'] = $level;
                    //把陣列放到list中
                    $list[] = $value;
                    //把這個節點從陣列中移除,減少後續遞迴消耗
                    unset($array[$key]);
                    //開始遞迴,查詢父ID為該節點ID的節點,級別則為原級別+1
                    $this->getTree($array, $value['id'], $level+1);
    
                }
            }
            return $list;
         }
        輸出方法:
        $array = $this->getTree($array);
        foreach ($array as $vo) {
            echo str_repeat(\' - \', $vo[\'level\']).$vo[\'name\'].\' < br>\';
        }

我上面寫引入的效能 目前是差不多是 遞迴 10倍左右
引入響應資料快取的情況下是差不多67-100ms左右
遞迴的話 是差不多 600-不等 可能記憶體洩漏啊 或者其它的問題 反正極其不穩定
檢視效能地址
引入: http://dome.nekgod.cn/
遞迴:http://dome.nekgod.cn/recursion

相關文章