Maison > Article > développement back-end > Explication détaillée des nouvelles fonctionnalités de PHP7 Ce qu'il y aura dans PHP 7
PHP7 sera officiellement publié en décembre 2015, PHP7 sera un script PHP Un majeur La mise à jour de la version du langage apportera également des améliorations significatives des performances et de nouvelles fonctionnalités, ainsi que certaines fonctions obsolètes. Cette version se concentrera sur l'amélioration des performances et provient de la branche phpng dans l'arborescence des versions PHP. Lors de la conférence ZendCon de la société de la Silicon Valley, le fabricant d'outils PHP Zend Technologies a officiellement discuté des progrès de phpng et PHP7. "(Cette mise à niveau) vise vraiment à aider l'industrie à améliorer considérablement la vitesse d'exécution des applications, couplée aux autres améliorations que nous avons apportées à PHP", a déclaré Andy Termans, PDG de Zend, qui a participé au développement du langage PHP. et développement) exprimés.
Recommandé (gratuit) : PHP7
Jetons un coup d'oeil au moteur php7 et aux fonctionnalités données sur le site officiel :
1) PHP7 est deux fois plus rapide que PHP5.6
2) JIT - Compilateur Just in Time (Just In Time Editor) Il s'agit d'une technologie d'optimisation logicielle qui compile le bytecode en code machine au moment de l'exécution. D'un point de vue intuitif, il nous est facile de penser que le code machine peut être directement reconnu et exécuté par les ordinateurs, et qu'il est plus efficace que Zend de lire les opcodes et de les exécuter un par un. Parmi eux, HHVM (HipHop Virtual Machine, HHVM est une machine virtuelle PHP open source de Facebook) utilise JIT, ce qui améliore leur test de performances PHP d'un ordre de grandeur et publie des résultats de test choquants, ce qui nous fait également penser intuitivement que JIT est un puissant technologie qui transforme la pierre en or. En fait, en 2013, Brother Niao et Dmitry (l'un des principaux développeurs du langage PHP) ont fait une fois une tentative JIT sur la version PHP5.5 (elle n'a pas été publiée). Le processus d'exécution original de PHP5.5 consiste à compiler le code PHP en bytecode d'opcode via une analyse lexicale et syntaxique (le format est quelque peu similaire à l'assemblage). Ensuite, le moteur Zend lit ces instructions d'opcode, les analyse et les exécute une par une. 21 % du temps CPU est consacré à la gestion de la mémoire. 12 % du temps CPU est consacré aux opérations de table de hachage, principalement l'ajout, la suppression, la modification et la vérification des tableaux PHP. 30 % du temps CPU est consacré aux fonctions intégrées, telles que strlen. 25% du temps CPU est passé dans la VM (Zend Engine). Après analyse, deux conclusions ont été tirées : (1) Si les ByteCodes générés par JIT sont trop volumineux , entraînera une diminution du taux de réussite du cache CPU (CPU Cache Miss) Dans le code PHP5.5, comme il n'y a pas de définition de type évidente, l'inférence de type ne peut être compté sur. Définissez autant que possible les types de variables qui peuvent être déduits, puis, combinés à l'inférence de type, supprimez les codes de branche qui ne sont pas de ce type et générez un code machine directement exécutable. Cependant, l’inférence de type ne peut pas déduire tous les types. Dans WordPress, moins de 30 % des informations de type pouvant être déduites sont limitées, et le code de branche pouvant être réduit est limité. En conséquence, après JIT, le code machine est directement généré et les ByteCodes générés sont trop volumineux, ce qui entraîne finalement une diminution significative des accès au cache CPU (CPU Cache Miss). L'atteinte du cache du processeur signifie que lorsque le processeur lit et exécute des instructions, si les données requises ne peuvent pas être lues dans le cache de premier niveau (L1) du processeur, il doit continuer à rechercher vers le bas, jusqu'au cache de deuxième niveau (L2) et au cache de troisième niveau (L3), et éventuellement essayer de trouver les données d'instruction requises dans la zone mémoire, et l'écart de temps de lecture entre la mémoire et le cache CPU peut atteindre 100x niveau. Par conséquent, si les ByteCodes sont trop volumineux et le nombre d'instructions exécutées est trop important, le cache multi-niveaux ne peut pas accueillir autant de données et certaines instructions devront être stockées dans la zone mémoire. Les tailles des caches à tous les niveaux du processeur sont également limitées. L'image suivante représente les informations de configuration de l'Intel i7 920 : . Par conséquent, la diminution du taux de réussite du cache du processeur entraînera une augmentation importante et fastidieuse. D'un autre côté, l'amélioration des performances apportée par JIT est. également compensé par cela. Grâce au JIT, la surcharge de la VM peut être réduite dans le même temps, grâce à l'optimisation des instructions, le développement de la gestion de la mémoire peut être indirectement réduit car le nombre d'allocations de mémoire peut être réduit. Cependant, pour les vrais projets WordPress, seulement 25 % du temps CPU est consacré à la VM, et le principal problème et goulot d’étranglement ne réside pas réellement dans la VM. Par conséquent, le plan d’optimisation JIT n’a pas été inclus dans les fonctionnalités PHP7 de cette version. Cependant, il est probable qu’il soit implémenté dans une version ultérieure, ce qui mérite d’être attendu. (2) L'effet d'amélioration des performances JIT dépend du goulot d'étranglement réel du projet JIT a un performances élevées dans le benchmark L'amélioration en ampleur est due au fait que la quantité de code est relativement faible, que les ByteCodes finaux générés sont également relativement petits et que la principale surcharge réside dans la VM. Cependant, il n'y a pas d'amélioration évidente des performances dans le projet WordPress actuel, car le volume de code de WordPress est beaucoup plus important que celui du benchmark. Bien que JIT réduise la surcharge de la VM, il entraîne une diminution des accès au cache du processeur et de la mémoire supplémentaire. Les ByteCodes sont trop volumineux. La surcharge ne constitue finalement aucune amélioration. Différents types de projets auront des ratios de surcharge CPU différents et obtiendront également des résultats différents. Les tests de performances sans projets réels ne sont pas très représentatifs. 3). Changements dans Zval En fait, le véritable support de stockage de différents types de variables en PHP est Zval, qui se caractérise par sa tolérance et sa tolérance. Essentiellement, il s'agit d'une structure (struct) implémentée en langage C. Pour les étudiants qui écrivent du PHP, vous pouvez le comprendre comme quelque chose de similaire à un tableau. Zval de PHP5, la mémoire occupe 24 octets : Zval de PHP7, occupation de la mémoire 16 octets : Zval est passé de 24 octets à 16 octets. Pourquoi ai-je besoin d'ajouter un peu de base en langage C ici, pour aider les étudiants qui le sont ? pas familier avec C pour comprendre. Il existe une légère différence entre struct et union (union). Chaque variable membre de Struct occupe un espace mémoire indépendant, tandis que les variables membres de union partagent un espace mémoire (c'est-à-dire que si l'une des variables membres est modifiée, la l'espace public sera Après modification, il n'y aura aucun enregistrement d'autres variables membres). Par conséquent, bien qu’il semble y avoir beaucoup plus de variables membres, l’espace mémoire réellement occupé a diminué. De plus, il y a évidemment des fonctionnalités modifiées, certains types simples n'utilisent plus de références. Diagramme de structure Zval : Zval dans l'image se compose de deux 64 bits (1 octet = 8 bits, le bit est "bit"). le type est long ou bealoon, et la longueur n'excède pas 64 bits, il sera stocké directement en valeur, et il n'y aura pas de référence suivante. Lorsque le type de variable est un tableau, un objet, une chaîne, etc. qui dépasse 64 bits, la valeur stockée est un pointeur pointant vers l'adresse réelle de la structure de stockage. Pour les types de variables simples, le stockage Zval devient très simple et efficace. Types qui ne nécessitent pas de références : NULL, Boolean, Long, Double Types qui nécessitent des références : String, Array, Object, Resource, Reference 4). Le type interne zend_string Zend_string est la structure qui stocke réellement la chaîne, et le contenu réel sera stocké. in val(char , type de caractère), et val est un tableau de caractères d'une longueur de 1 (pratique pour l'occupation des variables membres). La dernière variable membre de la structure utilise un tableau char au lieu de char* Voici une petite astuce d'optimisation qui peut réduire le. Manque de cache CPU. Si vous utilisez un tableau de caractères, lorsque malloc s'applique à la mémoire de la structure ci-dessus, il est appliqué dans la même zone, généralement la longueur est sizeof(_zend_string) + l'espace de stockage réel des caractères. Cependant, si vous utilisez char*, ce qui est stocké à cet emplacement n'est qu'un pointeur et le stockage réel se trouve dans une autre zone mémoire indépendante. Comparaison de l'allocation de mémoire à l'aide de char[1] et char* : Du point de vue de la mise en œuvre logique, il n'y a en fait pas beaucoup de différence entre les deux et les effets sont très similaires. En fait, lorsque ces blocs mémoire sont chargés dans le CPU, ils apparaissent très différents. Étant donné que le premier est le même morceau de mémoire alloué en continu ensemble, il peut généralement être obtenu ensemble lorsque le processeur le lit (car il se trouvera dans le même niveau de cache). Quant à cette dernière, parce qu'elle contient des données de deux mémoires, lorsque le CPU lit la première mémoire, il est très probable que les données de la deuxième mémoire ne soient pas dans le même niveau de cache, le CPU doit donc chercher en dessous de L2 (cache secondaire). , ou même à La deuxième donnée mémoire souhaitée se trouve dans la zone mémoire. Cela entraînera un échec du cache du processeur et la différence de temps entre les deux peut atteindre 100 fois. De plus, lors de la copie de chaînes, en utilisant l'affectation de référence, zend_string peut éviter les copies en mémoire. 5). Modifications des tableaux PHP (HashTable et Zend Array) dans Dans le processus d'écriture de programmes PHP, le type le plus fréquemment utilisé est celui des tableaux. Les tableaux PHP5 sont implémentés à l'aide de HashTable. Pour résumer, il s'agit d'une table de hachage qui prend en charge les listes doublement liées. Elle prend non seulement en charge le mappage de hachage pour accéder aux éléments via des clés de tableau, mais peut également parcourir les éléments du tableau en accédant aux listes doublement liées via foreach. Table de hachage PHP5 : Cette image semble très compliquée, avec divers pointeurs qui sautent lorsque nous accédons au contenu d'un élément via la valeur clé, parfois. il faut trois sauts de pointeur pour trouver le bon contenu. Le point le plus important est que le stockage de ces éléments du tableau est dispersé dans différentes zones mémoire. De la même manière, lorsque le CPU lit, parce qu'ils ne sont probablement pas dans le cache de même niveau, le CPU devra chercher dans le cache de niveau inférieur ou même dans la zone mémoire, ce qui entraînera une diminution de l'accès au cache du CPU, et ainsi augmentant plus la consommation d'heure. Zend Array de PHP7 (capture d'écran de PPT) : Nouvelle version de la structure du tableau, Très simple et accrocheur. La plus grande caractéristique est que l'ensemble des éléments du tableau et la table de mappage de hachage sont tous connectés ensemble et alloués dans la même mémoire. Si vous parcourez un tableau d'entiers de type simple, l'efficacité sera très rapide, car les éléments du tableau (Bucket) eux-mêmes sont continuellement alloués dans la même mémoire, et le zval des éléments du tableau stockera les éléments entiers en interne et non Il existe également un lien externe de pointeur et toutes les données sont stockées dans la zone de mémoire actuelle. Bien sûr, la chose la plus importante est que cela peut éviter les échecs de cache du processeur (diminution du taux de réussite du cache du processeur). Modifications du tableau Zend : (1) La valeur par défaut du tableau est zval. (2) La taille de HashTable est réduite de 72 à 56 octets, soit une réduction de 22%. (3) La taille des buckets est passée de 72 à 32 octets, soit une réduction de 50 %. (4) L'espace mémoire des buckets d'éléments du tableau est alloué ensemble. (5) La clé de l'élément du tableau (Bucket.key) pointe vers zend_string. (6) La valeur de l'élément du tableau est intégrée dans le Bucket. (7) Réduisez les échecs de cache du processeur. 6). Convention d'appel de fonction (Convention d'appel de fonction) PHP7 amélioré Le mécanisme d'appel de fonction réduit certaines instructions et améliore l'efficacité d'exécution en optimisant le processus de transfert de paramètres. Mécanisme d'appel de fonction PHP5 (capture d'écran de PPT) : Dans l'image, les instructions send_val et les paramètres recv dans la pile vm sont les mêmes. PHP7 réduit ces deux duplications. l'optimisation sous-jacente du mécanisme d'appel de fonction. Mécanisme d'appel de fonction PHP7 (capture d'écran de PPT) : 7). Grâce aux définitions de macros et aux fonctions en ligne (inline), laissez le compilateur effectuer une partie du travail à l'avance Les définitions de macros en langage C seront exécutées lors de la phase de prétraitement (étape de compilation), complétant une partie du travail à l'avance sans allouer de mémoire lorsque le programme est en cours d'exécution. Des fonctions similaires aux fonctions peuvent être obtenues, mais il n'y a pas d'empilement ou de popping. des appels de fonction. La surcharge de la pile, l'efficacité sera plus élevée. La même chose est vraie pour les fonctions en ligne. Lors de la phase de prétraitement, les fonctions du programme sont remplacées par des corps de fonction. Lorsque le programme en cours d'exécution est exécuté ici, il n'y aura pas de surcharge d'appels de fonction. PHP7 a apporté de nombreuses optimisations dans ce domaine, mettant beaucoup de travail qui doit être effectué dans la phase d'exécution dans la phase de compilation. Par exemple, le jugement du type de paramètre (Parameters Parsing), étant donné que tous les caractères impliqués ici sont des constantes de caractères fixes, peut être effectué lors de l'étape de compilation, améliorant ainsi l'efficacité de l'exécution ultérieure. Par exemple, dans la figure ci-dessous, la façon de gérer le type de paramètre transmis est optimisée de la méthode d'écriture de gauche à la méthode d'écriture de macro à droite.
Exemples précis : Plus d'erreurs deviennent des exceptions capturables Cette interface est utilisée pour définir la structure d'héritage des exceptions sous forme d'interfaces. En conséquence, davantage d'erreurs dans PHP7 deviennent des exceptions capturables et sont renvoyées aux développeurs. Si elles ne sont pas détectées, ce sont des erreurs. Si elles sont détectées, elles deviennent des exceptions qui peuvent être gérées dans le programme. Ces erreurs captables sont généralement des erreurs qui ne causeront pas de dommages mortels au programme, comme une fonction qui n'existe pas. PHP7 facilite davantage le traitement des développeurs et leur donne un plus grand contrôle sur le programme. Parce que par défaut, l'erreur provoquera directement l'interruption du programme, et PHP7 offre la possibilité de la capturer et de la traiter, permettant au programme de continuer à s'exécuter, offrant ainsi aux programmeurs des choix plus flexibles. Par exemple, pour exécuter une fonction dont nous ne sommes pas sûrs qu'elle existe ou non, la méthode compatible PHP5 consiste à ajouter le jugement function_exist avant que la fonction ne soit appelée, tandis que PHP7 prend en charge la capture Comment gérer les exceptions. Par exemple dans l'image ci-dessous Arbre de syntaxe, arbre de syntaxe abstraite) AST joue le rôle d'un middleware dans le processus de compilation PHP, remplaçant la méthode originale consistant à cracher l'opcode directement depuis l'interpréteur, découplant l'interpréteur (analyseur) et le compilateur (compilateur) Cela peut réduire certains codes de piratage et, en même temps, rendre l'implémentation plus facile à comprendre et à maintenir. PHP5 : PHP7 : Plus d'informations AST : https://wiki.php.net/rfc/abstract_syntax_tree TLS natif (stockage local de thread natif, thread natif stockage local) PHP doit résoudre le problème de la « sécurité des threads » (TS, Thread Safe) en mode multi-thread (par exemple, les modes woker et event du serveur web Apache, qui sont multi-thread), car les threads partagent l'espace mémoire du processus, de sorte que chaque thread lui-même doit créer un espace privé d'une manière ou d'une autre pour sauvegarder ses propres données privées afin d'éviter une contamination mutuelle avec d'autres threads. La méthode adoptée par PHP5 consiste à maintenir un grand tableau global et à allouer un espace de stockage indépendant à chaque thread. Les threads accèdent à ce groupe de données global via leurs propres valeurs de clé. En PHP5, cette valeur de clé unique doit être transmise à chaque fonction qui doit utiliser des variables globales. PHP7 estime que cette méthode de transmission n'est pas conviviale et présente quelques problèmes. Par conséquent, essayez d’utiliser une variable globale spécifique au thread pour enregistrer cette valeur clé. Problèmes Native TLS associés : https://wiki.php.net/rfc/native-tls Opérateur de comparaison combiné (< ; =>) Combiné avec des opérateurs de comparaison (<=>) Déclarations de type de retour et déclarations de type scalaire déclaration de type scalaire Une caractéristique très importante du langage PHP est le « typage faible », qui rend les programmes PHP très faciles à écrire. Les débutants peuvent démarrer rapidement lorsqu'ils entrent en contact avec PHP. Cependant, cela s'accompagne également d'une certaine controverse. La prise en charge de la définition de types de variables peut être considérée comme un changement innovant. PHP commence à prendre en charge les définitions de types de manière facultative. De plus, une instruction switch declare(strict_type=1); Une fois cette instruction activée, elle forcera le programme sous le fichier actuel à suivre les types de transfert de paramètres de fonction stricts et les types de retour. Par exemple, une fonction d'ajout plus une définition de type peuvent être écrites comme ceci : Si combiné avec la commande de commutation de type forcé, cela peut devenir comme ceci : Si strict_type n'est pas activé, PHP essaiera de vous aider à le convertir au type requis. Après l'avoir activé, PHP n'effectuera plus de conversion de type. le type ne correspond pas, cela générera une erreur. C’est une excellente nouvelle pour les étudiants qui aiment les langues « fortement typées ». Introduction plus détaillée : https://wiki.php.net/rfc/scalar_type_hints_v5 Déclaration de type scalaire PHP7 RFC
Pourquoi passer directement de PHP5.6 à PHP7 (Raisons données pour lesquelles nous devons passer à PHP 7) Il y a plusieurs raisons pour lesquelles nous ne devrions pas t réutiliser la version 6 pour la prochaine version majeure de PHP. cli cgi fpm apache (FastCGI et FPM pourraient être beaucoup plus rapides si mod_php est construit en tant que PIC) apache2handler bcmath bz2 calendrier com_dotnet ctype curl date dba dom enchanter ereg exif fileinfo filtre ftp gd gettext gmp hash iconv imap intl json ldap libxml mbstring mcrypt mysql mysqli mysqlnd odbc (testé avec pilote unixODBC et MySQL) openssl OPcache pcntl pcre PDO pdo_firebird pdo_mysql PDO_ODBC (testé avec unixODBC et le pilote MySQL) pdo_pgsql pdo_sqlite pgsql Phar posix pspell readline recoder Réflexion session shmop SimpleXML snmp savon prises SPL sqlite3 standard sysvmsg sysvsem sysvshm bien rangé tokenizer wddx xml xmlreader xmlwriter xsl zip zlib interbase mssql oci8 pdo_dblib pdo_oci sybase_ct PHP7 VS PHP5.6 1. Opcache N'oubliez pas d'activer Zend Opcache , Étant donné que PHP7 est plus rapide que PHP-5.6 avec Opcache activé même sans Opcache activé, certaines personnes n'ont pas activé Opcache au cours de la période de test précédente. L'activation d'Opcache est très simple, ajoutez le fichier de configuration php.ini : zend_extension=opcache.so opcache.enable=1 opcache.enable_cli=1" 2. Utilisez un nouveau compilateur Utilisez un compilateur plus récent, GCC 4.8 est recommandé ci-dessus, car seul PHP avec GCC 4.8 ou supérieur activera Global Register pour la prise en charge d'opline et d'execute_data, cela entraînera une amélioration des performances de 5 % (mesurée du point de vue QPS de Wordpres) En fait, les versions antérieures à GCC 4.8 le prennent également en charge, mais nous avons constaté qu'il y a des bugs dans sa prise en charge, cette fonctionnalité doit donc être activée dans la version 4.8 ou supérieure. 3. HugePage Mon article précédent a également présenté : Hugepage pour rendre votre PHP7 plus rapide, activez d'abord HugePages dans le système, puis activez huge_code_pages d'Opcache. En prenant mon CentOS 6.5 comme exemple, passez : $sudo sysctl vm.nr_hugepages=512 Allouer 512 pages géantes réservées : $ cat /proc/meminfo | grep Énorme AnonHugePages : 106496 Ko HugePages_Total : 512 HugePages_Free : 504 HugePages_Rsvd : 27 HugePages_Surp : 0 Hugepagesize : 2048 ko Puis en php Ajouter au .ini : opcache.huge_code_pages=1 De cette façon, PHP utilisera de grandes pages de mémoire pour enregistrer son propre segment de texte et l'énorme allocation de mémoire, réduisant ainsi les échecs TLB et améliorant ainsi les performances. 4. Cache de fichiers Opcache Activer le fichier Opcache cache Cache (expérimental), en activant cette option, nous pouvons laisser Opcache mettre en cache le cache des opcodes dans un fichier externe. Pour certains scripts, il y aura une amélioration significative des performances. Ajouter dans php.ini : opcache.file_cache=/tmp De cette façon, PHP mettra en cache certains fichiers d'exportation binaires Opcode dans le répertoire /tmp, qui peuvent exister tout au long du cycle de vie de PHP. 5. PGO Mes articles précédents : Faire votre PHP7 plus rapide (GCC PGO) a également été introduit. Si votre PHP est dédié à servir un projet, comme uniquement pour votre WordPress, ou Drupal, ou autre chose, alors vous pouvez essayer d'améliorer PHP via PGO, spécialement conçu pour. améliorer les performances de votre projet. Plus précisément, WordPress 4.1 est utilisé comme scénario d'optimisation. Tout d'abord, lors de la compilation de PHP : $ make prof-gen Ensuite entraînez PHP avec votre projet, par exemple pour WordPress : $ sapi/cgi/php-cgi -T 100 /home/huixinchen/local/www/htdocs/wordpress/index.php >/dev/null également Laissez simplement php-cgi exécuter la page d'accueil de WordPress 100 fois pour générer des informations de profil au cours du processus. Enfin : $ faire du prof-clean $ faire un usage professionnel Le PHP7 que vous compilez en ce moment est fait sur mesure pour votre projet Construit pour la version compilée la plus performante. C'est tout pour l'instant, j'en ajouterai plus quand j'y penserai plus tard, tout le monde est invité à l'essayer, merci. PHP 7.0.0 RC 2 a publié de nouvelles fonctionnalités
// PHP 7之前的写法:比较两个数的大小
function order_func($a, $b) {
return ($a < $b) ? -1 : (($a > $b) ? 1 : 0);
}
// PHP新增的操作符 <=>,perfect
function order_func($a, $b) {
return $a <=> $b;
}
SAPI pris en charge
Extensions prises en charge
Extensions non prises en charge (pas encore converties)
让PHP 7达到最高性能的几个Conseils
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!