PHP Opcode: Verbetering van toepassingsprestaties zonder wijziging van uw code

De PHP-opcode gegenereerd door de PHP-engine wordt sterk beïnvloed door de manier waarop u uw code schrijft, niet alleen in termen van het aantal statements om een taak uit te voeren. Duidelijk, dat maakt heel veel verschil, en ik denk dat dat voor u ook duidelijk is.

Wat minder duidelijk kan zijn, is dat zelfs de syntaxis van de code de gegenereerde opcode compleet kan veranderen, waardoor veel extra overhead voor de CPU van de machine optreedt om exact dezelfde code uit te voeren.

In de afgelopen paar jaren is mijn SaaS-product heel wat gegroeid, en heb ik de gelegenheid gehad om steeds dieper te gaan in optimatietechnieken om mijn werklast zo efficiënt mogelijk uit te voeren.

De resultaten die ik zag zijn indrukwekkend en hebben mij heel wat geholpen om vrij kapitaal vrij te maken om mijn SaaS-reis voort te zetten.

Op dit moment bewerkt de PHP-process van mijn SaaS-product meer dan 1,2 miljard (met een “b”) data-pakketten per dag op een machine met 2vCPU en 8GB geheugen. Ik gebruik een AWS autoscalinggroep om meer flexibiliteit te krijgen in geval van onvoorspelbare pieken, maar het wordt vaak maar een tweede machine toegevoegd (één/twee keer per week).

Laten we nu aan de onderwerpen van het artikel gaan. Ik denk dat het voor u erg interessant zal zijn.

Wat is PHP Opcode?

PHP opcode staat voor operation code, en verwijst naar de low-level instructies die worden uitgevoerd door de PHP-engine nadat de PHP-broncode die u schrijft is gecompileerd.

In PHP gebeurt de codecompilatie op runtime: in de basis, de eerste keer dat uw code wordt opgenomen door de PHP-engine zal deze in dit machinevriendelijke code worden gecompileerd, opgeslagen (zodat de engine dezelfde code niet opnieuw moet compileren) en vervolgens uitgevoerd.

Dit is een eenvoudige weergave van het proces:

PHP Opcode Caching

Het cachen van PHP opcodes laat u drie stappen in het uitvoeren van de code besparen: het parsen van het ruwe PHP-code, tokenisatie en compilatie.

Eens de opcode voor de eerste keer is gegenereerd, wordt hij in de geheugen opgeslagen zodat hij in volgende aanvragen hergebruikt kan worden. Dit reduceert het nodige voor de PHP-engine om elke keer dat hetzelfde PHP-code wordt uitgevoerd opnieuw te compileren, wat veel CPU- en geheugenverbruik bespaart.

De meest gebruikte opcode cache in PHP is OPCache, die standaard is ingevoegd vanaf PHP 5.5 tot de meest recente versies. Het is zeer efficiënt en breed ondersteund.

Het cachen van de voorgecompileerde script bytecode vereist het opnieuw invalidatie van de cache na elke deploy. Dit omdat de bytecode versie van gewijzigde bestanden in de cache zit, zal PHP de oude versie van het code blijven uitvoeren totdat u de opcode cache opruimt, zodat de nieuwe code opnieuw gecompileerd wordt en een nieuw cache item wordt gegenereerd.

Hoe PHP Opcode te Onderzoeken

Om te begrijpen hoe verschillende syntaxis het script opcode kan beïnvloeden, hebben we een manier nodig om de door de PHP-engine gegenereerde gecompileerde code te grijpen.

Er zijn twee manieren om de opcode te krijgen.

OPCache Native Functions

Als u de OPCache-extensie ingeschakeld hebt op uw machine, kunt u zijn eigen functies gebruiken om de opcode van een specifiek PHP-bestand te krijgen:

PHP

 

VLD (Vulcan Logic Disassembler) PHP Extension

VLD is een populair PHP-extensie die gecompileerd PHP-code ontbreekt en de opcode uitvoert. Het is een krachtig gereedschap voor het begrijpen hoe PHP uw code interpreteert en uitvoert. Na de installatie kunt u een PHP-script met VLD ingeschakeld uitvoeren door de php opdracht te gebruiken met de -d opties:

Shell

 

De uitvoer zal gedetailleerde informatie bevatten over de gecompileerde opcode, inclusief elke bewerking, zijn geassocieerde coderegel en meer.

Gebruik 3v4l (Afkorting voor EVAL)

3v4l is een zeer nuttig online gereedschap dat u toestaat de opcode te bekijken die wordt gegenereerd door PHP-code die u in het editor typ. Het is in essentie een PHP-server met VLD geïnstalleerd zodat het de VLD-uitvoer kan afnemen en de opcode in de browser kan weergeven.

Omdat het gratis is, zullen we dit online gereedschap gebruiken voor de volgende analyses.

Hoe efficiënte PHP-opcode te genereren

3v4l is perfect voor het begrijpen hoe de code syntaxis die we gebruiken kan beïnvloeden of bevorderen of verminderen de resulterende PHP-opcode. Begin nu met het plakken van de code onderaan in 3v4l. behoud de configuratie “alle ondersteunde versies” en klik op “eval”.

PHP

 

Na het uitvoeren van de code zal een tabbladmenu aan de onderkant verschijnen. Ga naar de VLD tabel om de correspondente Opcode te visualiseren.

Shell

 

Merk op dat de eerste operatie INIT_NS_FCALL_BY_NAME is. De interpretator bouwt de naam van de functie op door middel van het namespace van het huidige bestand, maar het bestaat niet in het App\Example namespace — dus hoe werkt het?

De interpretator zal controleren of de functie bestaat in het huidige namespace. Als dat niet zo is, zal hij proberen de corresponderende core functie aan te roepen.

Hier hebben we de kans om aan de interpretator te vertellen om deze dubbele controle te vermijden en de core functie direct uit te voeren.

Probeer een backslash (\) voor strlen toe te voegen en klik op “eval”:

PHP

 

In de VLD tabblad, kunt u nu de opcode zien met slechts één statement.

Omdat u de exacte locatie van de functie heeft doorgegeven, heeft het geen behoefte om naar een fallback te kijken.

Als u geen gebruik wilt maken van het backslash, kunt u de functie importeren net als elke andere klasse uit het root namespace:

PHP

 

gebruik Automatische Opcode Optimalisaties

Er zijn ook veel interne automatismen van de PHP-engine om geoptimaliseerde opcodes te genereren door statische expressies te evalueren in voorgaande tijd. Dit was één van de belangrijkste redenen voor de grote prestatiesterving van PHP sinds versie 7.x.

Het inzicht in deze dynamiek kan u echt helpen om de resourceverbruik te verminderen en kosten te besparen. Na deze onderzoek heb ik deze trucken beginnen toe te passen in het gehele code.

Laat me een voorbeeld laten zien dat gebruik maakt van PHP-constanten. Voer dit script uit in 3v4l:

PHP

 

Bekijk de eerste twee lijnen van de PHP opcode:

FETCH_CONSTANT probeert de waarde van PHP_OS te halen uit het huidige namespace, en zal kijken in het globale namespace aangezien het hier niet bestaat. Vervolgens executeert de instructie IS_IDENTICAL de IF statement.

Probeer nu een backslash toe te voegen aan een constante:

PHP

 

Als je de opcode ziet, merkt de engine dat het niet nodig is de constante te halen omdat nu duidelijk is waar ze is, en omdat het een statische waarde is, heeft het hem reeds in de geheugen.

Ook is de IF statement verdwenen omdat de andere kant van de IS_IDENTICAL statement een statische string (‘Linux’) is, zodat de IF als “true” gemarkeerd kan worden zonder de overhead van het interpreteren ervan bij elke uitvoering.

Dit is waarom je veel macht hebt om de uiteindelijke prestaties van uw PHP-code te beïnvloeden.

Conclusie

Ik hoop dat dit een interessant onderwerp was.als ik aan het begin van het artikel vermeldde dat ik veel voordelen behaalde door deze tactiek te gebruiken, en eigenlijk worden ze ook in onze pakketten gebruikt.

U kunt hier een voorbeeld zien van hoe ik deze tips in ons PHP-pakket gebruikte om zijn prestaties te optimaliseren.

Als u meer wilt leren over de uitdagingen van het opbouwen van een door ontwikkelaars aangeleide bedrijf, kunt u me volgen op LinkedIn.

Source:
https://dzone.com/articles/php-opcode-improve-application-performance