2010-01-21 6 views
2

J'écris un analyseur de balises de texte et j'utilise actuellement cette méthode récursive pour créer des balises de n mots. Existe-t-il un moyen de le faire de manière non récursive ou au moins d'être optimisé? Supposons que $ this-> dataArray peut être un très grand tableau.Optimisation d'une méthode récursive En PHP

/** 
* A recursive function to add phrases to the tagTracker array 
* @param string $data 
* @param int $currentIndex 
* @param int $depth 
*/ 
protected function compilePhrase($data, $currentIndex, $depth){ 
    if (!empty($data)){ 
     if ($depth >= $this->phraseStart){ 
      $this->addDataCount($data, $depth); 
     } 
     if ($depth < $this->phraseDepth){ 
      $currentIndex = $currentIndex + 1; 
      //$this->dataArray is an array containing all words in the text 
      $data .= ' '.$this->dataArray[$currentIndex]; 
      $depth += 1; 
      $this->compilePhrase($data, $currentIndex, $depth); 
     } 
    } 
} 

Répondre

3

Voyez si vous pouvez utiliser tail recursion plutôt que récursion basée sur les appels. Certains réécritures peuvent être nécessaires, mais un coup d'oeil rapide dit que c'est bien de le faire.

La récursion de queue est idéale pour un sous-ensemble de fonctions récursives, et il est recommandé de repérer les boucles qui peuvent remplacer la récursion et comment réécrire. En disant ça, je ne sais pas quel est le coût de l'appel à l'intérieur de PHP. Peut-être juste une configuration de type pointeur de retour plutôt qu'un vrai vent de pile.

Il s'avère à peu près la même chose. PHP optimise-t-il les appels récursifs?

Voici ma réécriture, mais attention, mon cerveau est actuellement privé de sommeil!

protected function compilePhrase($data, $currentIndex, $depth){ 
    /* Loop until break condition */ 
    while(true) { 
     if (!empty($data)){ 
      if ($depth >= $this->phraseStart){ 
       $this->addDataCount($data, $depth); 
      } 
      if ($depth < $this->phraseDepth){ 
       $currentIndex = $currentIndex + 1; 
       // A test here might be better than the !empty($data) 
       // in the IF condition. Check array bounds, assuming 
       // array is not threaded or anything 
       $data .= ' '.$this->dataArray[$currentIndex]; 
       $depth += 1; 
      }else{ 
       break; 
      } 
     }else{ 
      break; 
     } 
    } 
    /* Finish up here */ 
    return($this->dataArray); 
} 
+0

Hmm. Cela fonctionne si vous ajoutez un else/break pour la seconde instruction if imbriquée. Cependant, il semble en moyenne à peu près la même vitesse que la fonction récursive. – VirtuosiMedia

+0

Cool, va éditer. –

+1

La récursivité de la queue n'est généralement pas considérée comme une optimisation de la vitesse (bien que le déroulement de la pile prenne du temps, il doit être faible par rapport à l'ensemble de la concaténation de chaîne en cours). C'est une optimisation de l'espace pour vous empêcher de déborder la pile. –

Questions connexes