10
votes

Exploser un tableau dans un paramètre de boucle de forach

$test = explode(',' $foo);
foreach($test as $bar) { ... }

1 commentaires

@ Tomalak-Geretkal merci, c'est une structure de contrôle.


4 Réponses :


1
votes

efficacité dans quel sens? Gestion de la mémoire, ou processeur? Le processeur ne ferait pas la différence, pour la mémoire - vous pouvez toujours faire $ foo = exploser (',', $ foo)


0 commentaires

6
votes

Dans le premier cas, PHP l'explose une fois et la maintient en mémoire.

L'impact de la création d'une variable différente ou de l'autre sens serait négligeable. L'interpréteur PHP devra maintenir un pointeur sur un emplacement de l'élément suivant s'ils sont définis par l'utilisateur ou non.


0 commentaires

3
votes

Du point de mémoire, il ne fera pas la différence, car php utilise le copie sur le concept d'écriture .

En dehors de cela, je choisirai personnellement la première option - c'est une ligne de moins, mais pas moins lisible (IMHO!).


1 commentaires

@Ryan: Ooops, je voulais dire le premier;)



24
votes

Je pourrais faire une supposition éduquée, mais essayons-le em>!

J'ai pensé qu'il y avait trois moyens principaux de s'approcher de cela. p>

  1. exploser et assigner avant d'entrer dans la boucle li>
  2. exploser dans la boucle, pas d'affectation li>
  3. String Tokenize Li> ol>

    Mes hypothèses: p>

    1. consommez probablement plus de mémoire en raison de l'affectation li>
    2. probablement identique à # 1 ou n ° 3, pas sûr de quoi LI>
    3. probablement à la fois plus rapide et beaucoup plus petit pas de mémoire de mémoire li> OL>

      Approche H2>

      Voici mon script de test: p> xxx pré>

      et voici les trois versions: p>

      1 ) P>

      // explode separately 
      $arr = explode(',', $listStr);
      foreach ($arr as $val) {strlen($val);}
      
      • Dans la grande image, l'une de ces méthodes est suffisamment rapide pour une liste de "taille raisonnable" (peu de centaines de mille). Li>
      • Si vous êtes itération sur quelque chose énorme em>, la différence de temps est relativement mineure mais une utilisation de la mémoire pourrait être différente d'un ordre de magnitude! Li>
      • Lorsque vous exploser () code> en ligne sans pré-assignation, c'est un peu plus lent pour une raison quelconque. Li>
      • Étonnamment, la tokénisation est un peu plus lente em> que d'itération explicitement d'une matrice déclarée. Travailler sur une telle échelle, je pense que c'est due à la pile d'appels sur le dessus de la création d'un appel de fonction à strtok () code> chaque itération. Plus sur ce ci-dessous. LI> ul>

        en termes de nombre d'appels de fonction, Exploser () CODE> ING TOPS TOKENISANT. o (1) em> vs o (n) p>

        J'ai ajouté un bonus au graphique où je exécute la méthode 1) avec un appel de fonction dans la boucle . J'ai utilisé SHLEN ($ VAL) code>, pensant que ce serait un temps d'exécution relativement similaire. C'est sujet à un débat, mais je n'essayais que de faire un point général. (Je n'ai que couru strallen ($ val) code> et ignoré sa sortie. Je l'ai dit pas em> l'attribuez à rien, car une mission serait un coût de temps supplémentaire.) p> xxx pré>

        Comme vous pouvez le constater dans la table des résultats, il devient alors la méthode la plus lente des trois. P>

        Pensée finale H2>

        Ceci est Intéressant à savoir, mais ma suggestion est de faire ce que vous ressentez est le plus lisible / maintenu. Seulement si vous avez vraiment affaire à un jeu de données de manière significative, vous vous inquiétez de ces micro-optimisations. P> P>


3 commentaires

Il est assez évident que $ x = ...; foreach ($ x utilisera plus de mémoire après la boucle que foreach (... . Simplement parce que la variable x il est toujours intacte après-mots. Mais cela n'a pas beaucoup d'importance. La variable sera détruite sur un retour ou, si la mémoire est critique, peut simplement être nonset . Qu'est-ce que est intéressant est l'utilisation de la mémoire maximale, car seulement cela compte vers la mémoire_limit. Et ici je suis très confiant que cela vous donnera assez semblable Résultats pour les deux variantes de Foreach. N'oubliez pas: si vous êtes une mémoire "Benchmarking", vous souhaitez normalement utiliser Memory_Get_peak_USAGE , pas ...


... memory_get_usage . Le fait que les n ° 2 et les n ° 3 sont identiques en mémoire rendent également du fait que vous ne faites que mesurer l'utilisation de la mémoire après la boucle. La mémoire de pointe serait probablement plus petite pour strtok . Cela n'a rien à voir avec PHP Transformant le exploser à la jonction de la jonction lors d'une boucle. Et concernant votre dernier exemple: les appels de fonction sont coûteux en PHP;) Vous SHLEN ($ VAL); impliquerait d'exécuter cinq opcodes.


Merci, il est également important de mentionner version et os pour ces résultats.