Différence de vitesse entre l'utilisation de chaînes en ligne et la concaténation en php5 ?

StackOverflow https://stackoverflow.com/questions/13620

  •  08-06-2019
  •  | 
  •  

Question

(supposons php5) considérez

<?php

    $foo = 'some words';

    //case 1
    print "these are $foo";

    //case 2
    print "these are {$foo}";

    //case 3
    print 'these are ' . $foo;
?>

Y a-t-il une grande différence entre 1 et 2 ?

Sinon, qu'en est-il entre 1/2 et 3 ?

Était-ce utile?

La solution

Eh bien, comme pour toutes les questions « Qu'est-ce qui pourrait être plus rapide dans la vraie vie », il n'y a rien de mieux qu'un test réel.

function timeFunc($function, $runs)
{
  $times = array();

  for ($i = 0; $i < $runs; $i++)
  {
    $time = microtime();
    call_user_func($function);
    $times[$i] = microtime() - $time;
  }

  return array_sum($times) / $runs;
}

function Method1()
{ 
  $foo = 'some words';
  for ($i = 0; $i < 10000; $i++)
    $t = "these are $foo";
}

function Method2()
{
  $foo = 'some words';
  for ($i = 0; $i < 10000; $i++)
    $t = "these are {$foo}";
}

function Method3()
 {
  $foo = 'some words';
  for ($i = 0; $i < 10000; $i++)
    $t = "these are " . $foo;
}

print timeFunc('Method1', 10) . "\n";
print timeFunc('Method2', 10) . "\n";
print timeFunc('Method3', 10) . "\n";

Donnez-lui quelques essais pour tout pager, puis...

0.0035568

0.0035388

0.0025394

Ainsi, comme prévu, les interpolations sont pratiquement identiques (différences de niveau de bruit, probablement dues aux caractères supplémentaires que le moteur d'interpolation doit gérer).La concaténation directe représente environ 66 % de la vitesse, ce qui n'est pas un grand choc.L'analyseur d'interpolation recherchera, ne trouvera rien à faire, puis terminera par une simple concatération de chaîne interne.Même si le concat était coûteux, l'interpolateur devra quand même le faire, après tout le travail pour analyser la variable et couper/copier la chaîne d'origine.

Mises à jour par Somnath :

J'ai ajouté Method4() à la logique en temps réel ci-dessus.

function Method4()
 {
  $foo = 'some words';
  for ($i = 0; $i < 10000; $i++)
    $t = 'these are ' . $foo;
}

print timeFunc('Method4', 10) . "\n";

Results were:

0.0014739
0.0015574
0.0011955
0.001169

Lorsque vous déclarez simplement une chaîne et que vous n'avez pas besoin d'analyser cette chaîne également, alors pourquoi confondre le débogueur PHP pour l'analyser.J'espère que vous avez compris mon point.

Autres conseils

La différence de performances a été non pertinent depuis au moins janvier 2012, et probablement avant :

Single quotes: 0.061846971511841 seconds
Double quotes: 0.061599016189575 seconds

Les versions antérieures de PHP pouvaient avoir une différence - personnellement, je préfère les guillemets simples aux guillemets doubles, c'était donc une différence pratique.La conclusion de l’article fait valoir un excellent point :

Ne vous fiez jamais à une statistique que vous n’avez pas forgée vous-même.

(Bien que l'article cite cette phrase, la boutade originale était probablement fausse. attribué à Winston Churchill, inventé par le ministère de la propagande de Joseph Goebbels pour dépeindre Churchill comme un menteur :

Je traue keiner Statistik, die je ne suis pas moi-même gefälscht habe.

Cela se traduit vaguement par : « Je ne fais pas confiance à une statistique selon laquelle je n’ai pas simulé moi-même. »)

Benchmarks en direct :

http://phpbench.com/

Il existe en fait une différence subtile lors de la concaténation de variables avec des guillemets simples ou doubles.

Test de @Adam utilisé

"these are " . $foo

notez que ce qui suit est encore plus rapide :

'these are ' . $foo;

cela est dû au fait qu'une "chaîne" entre guillemets doubles est évaluée, alors qu'une "chaîne" entre guillemets simples est simplement prise telle quelle...

Ne vous attardez pas trop à essayer d'optimiser les opérations sur les chaînes en PHP.Concaténation vs.l'interpolation n'a aucun sens (dans les performances réelles) si vos requêtes de base de données sont mal écrites ou si vous n'utilisez aucun type de schéma de mise en cache.Écrivez vos opérations sur les chaînes de manière à ce que le débogage ultérieur de votre code soit facile, les différences de performances étant négligeables.

@uberfuzzy En supposant qu'il ne s'agisse que d'une question sur les détails du langage, je suppose que ça va.J'essaie simplement d'ajouter à la conversation que comparer les performances entre guillemets simples, guillemets doubles et heredoc dans les applications du monde réel n'a aucun sens par rapport aux véritables puits de performances, tels que les requêtes de base de données médiocres.

Les différences de temps d'exécution sont totalement négligeables.

S'il te plait regarde

Ne perdez pas de temps sur des micro-optimisations comme celle-ci.Utilisez un profileur pour mesurer les performances de votre application dans un scénario réel, puis optimisez là où cela est réellement nécessaire.L'optimisation d'une seule requête de base de données bâclée est susceptible d'apporter une amélioration des performances plus importante que l'application de micro-optimisations sur tout votre code.

Il me semble que le développeur du logiciel de forum, Vanilla, a remplacé tous les guillemets doubles de son code par des guillemets simples et a remarqué une augmentation raisonnable des performances.

Cependant, je n'arrive pas à trouver un lien vers la discussion pour le moment.

il y a une différence lors de la concaténation de variables...et que faites-vous avec le résultat...et si ce que vous faites est de le vider vers la sortie, la mise en mémoire tampon de sortie est-elle activée ou non.

aussi, quelle est la situation de la mémoire du serveur ?généralement, la gestion de la mémoire sur une plate-forme de niveau supérieur est pire que celle sur les plates-formes inférieures...

$a = 'parse' . $this; 

gère la mémoire au niveau de la plateforme de code utilisateur...

$a = "parse $this";

gère la mémoire au niveau de la plate-forme de code système php...

donc ces benchmarks liés au CPU ne racontent pas toute l’histoire.

exécuter le benchmark 1 000 fois par rapport à l'exécution du benchmark 1 000 fois sur un serveur qui tente d'exécuter la même simulation 1 000 fois simultanément...vous pourriez obtenir des résultats radicalement différents selon la portée de l'application.

Les guillemets doubles peuvent être beaucoup plus lents.J'ai lu à plusieurs endroits qu'il valait mieux faire ça

'parse me '.$i.' times'

que

"parse me $i times"

Bien que je dirais que le second vous a donné un code plus lisible.

Juste pour ajouter quelque chose d'autre au mélange, si vous utilisez une variable dans une syntaxe de chaîne entre guillemets doubles :

$foo = "hello {$bar}";

est plus rapide que

$foo = "hello $bar";

et les deux sont plus rapides que

$foo = 'hello' . $bar; 

Il n'y a pratiquement aucune différence !Voir les horaires : http://micro-optimization.com/single-vs-double-quotes

Il convient de noter que lorsqu'on utilise une version modifiée de l'exemple d'Adam Wright avec 3 variables, les résultats sont inversés et les deux premières fonctions sont en réalité plus rapides et cohérentes.C'est avec PHP 7.1 sur CLI :

function timeFunc($function, $runs)
{
    $times = array();

    for ($i = 0; $i < $runs; $i++)
    {
        $time = microtime();
        call_user_func($function);
        @$times[$i] = microtime() - $time;
    }

    return array_sum($times) / $runs;
}

function Method1()
{ 
    $foo = 'some words';
    $bar = 'other words';
    $bas = 3;
    for ($i = 0; $i < 10000; $i++)
         $t = "these are $foo, $bar and $bas";
}

function Method2()
{
    $foo = 'some words';
    $bar = 'other words';
    $bas = 3;
    for ($i = 0; $i < 10000; $i++)
         $t = "these are {$foo}, {$bar} and {$bas}";
}

function Method3()
{
    $foo = 'some words';
    $bar = 'other words';
    $bas = 3;
    for ($i = 0; $i < 10000; $i++)
         $t = "these are " . $foo . ", " . $bar . " and " .$bas;
}

print timeFunc('Method1', 10) . "\n";
print timeFunc('Method2', 10) . "\n";
print timeFunc('Method3', 10) . "\n";

J'ai également essayé avec « 3 » au lieu du simple nombre entier 3, mais j'obtiens le même genre de résultats.

Avec $bas = 3 :

0.0016254
0.0015719
0.0019806

Avec $bas = '3' :

0.0016495
0.0015608
0.0022755

Il est à noter que ces résultats varient fortement (j'obtiens des variations de l'ordre de 300%), mais les moyennes semblent relativement stables et montrent presque (9 cas sur 10) toujours une exécution plus rapide pour les 2 premières méthodes, la méthode 2 étant toujours légèrement plus rapide que la méthode 1.

En conclusion:ce qui est vrai pour une seule opération (qu'il s'agisse d'une interpolation ou d'une concaténation) ne l'est pas toujours pour les opérations combinées.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top