<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Luiz Schons – Performance</title><link>https://luizschons.com/pt-br/tags/performance/</link><description>Recent content in Performance on Luiz Schons</description><generator>Hugo -- gohugo.io</generator><language>pt-br</language><lastBuildDate>Tue, 28 May 2024 00:00:00 -0300</lastBuildDate><atom:link href="https://luizschons.com/pt-br/tags/performance/index.xml" rel="self" type="application/rss+xml"/><item><title>JIT (Just in Time) — PHP</title><link>https://luizschons.com/pt-br/posts/jit-just-in-time-php/</link><pubDate>Tue, 28 May 2024 00:00:00 -0300</pubDate><guid>https://luizschons.com/pt-br/posts/jit-just-in-time-php/</guid><description>
&lt;p&gt;Se você ainda não atualizou para o PHP 8.0 ou maior, está na hora de fazer isso. O PHP 8.0 foi lançado em 26 de novembro de 2020 e trouxe o JIT (Just In Time) e é sobre ele que vamos falar hoje.&lt;/p&gt;
&lt;h2 id="heading-codigo-opc"&gt;Código OPC&lt;/h2&gt;
&lt;p&gt;Quando você executa um script PHP, o PHP o compila para um código intermediário chamado de código OPC (PHP Opcode). O código OPC é então executado pela máquina virtual Zend.&lt;/p&gt;
&lt;p&gt;Segue um exemplo de código PHP e seu código OPC:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PHP:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;M_PI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Result: &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Código OPC:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Finding entry points
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Branch analysis from position: 0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1 jumps found. (Code = 62) Position 1 = -2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;filename: /in/ceTlX
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;function name: (null)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;number of ops: 9
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;compiled vars: !0 = $a, !1 = $b
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;line #* E I O op fetch ext return operands
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-------------------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 2 0 E &amp;gt; ASSIGN !0, 3.14159
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 3 1 INIT_FCALL &amp;#39;sin&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 2 SEND_VAR !0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 3 DO_ICALL $3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 4 ADD ~4 10, $3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 5 ASSIGN !1, ~4
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 4 6 ECHO &amp;#39;Result%3A+&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 7 ECHO !1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 5 8 &amp;gt; RETURN 1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Basicamente, o código OPC é uma sequência de instruções que a máquina virtual Zend executa.&lt;/p&gt;
&lt;h2 id="heading-jit"&gt;&lt;strong&gt;JIT&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Mas onde o JIT entra nisso? O JIT é um compilador que compila o código OPC em código de máquina nativo. Isso significa que o JIT compila o código OPC em código de máquina que a CPU pode executar diretamente.&lt;/p&gt;
&lt;p&gt;Dessa forma não usamos mais a máquina virtual Zend para executar o código OPC, mas sim o código de máquina nativo gerado pelo JIT.&lt;/p&gt;
&lt;h2 id="heading-habilitando-o-jit"&gt;&lt;strong&gt;Habilitando o JIT&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;O JIT não é habilitado por padrão. Para habilitá-lo, você precisa de alguns passos adicionais.&lt;/p&gt;
&lt;p&gt;Primeiro, você precisa instalar a extensão &lt;code&gt;opcache&lt;/code&gt;:&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install php8.0-opcache&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Depois, você precisa habilitar o JIT no arquivo de configuração do PHP (&lt;code&gt;php.ini&lt;/code&gt;):&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;opcache&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;opcache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;enable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;opcache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jit_buffer_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="nx"&gt;M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;opcache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;tracing&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;opcache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1205&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;opcache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;enable_cli&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Aqui, estamos habilitando o JIT e definindo o tamanho do buffer JIT para 100 MB. O JIT pode operar em dois modos: &lt;code&gt;tracing&lt;/code&gt; e &lt;code&gt;function&lt;/code&gt;. O modo &lt;code&gt;tracing&lt;/code&gt; é o modo padrão e é mais rápido, mas o modo &lt;code&gt;function&lt;/code&gt; é mais preciso.&lt;/p&gt;
&lt;p&gt;Para entender melhor a diferença entre os modos &lt;code&gt;tracing&lt;/code&gt; e &lt;code&gt;function&lt;/code&gt;, recomendo a leitura da &lt;a target="_blank" href="https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.jit"&gt;documentação oficial&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;E depois habilitamos o JIT para a linha de comando (&lt;code&gt;opcache.enable_cli=1&lt;/code&gt;). &lt;/p&gt;
&lt;h3 id="heading-benchmark"&gt;&lt;strong&gt;Benchmark&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Se você roda o PHP na Web, o JIT pode não fazer muita diferença. Mas se você roda scripts PHP na linha de comando, o JIT pode trazer um grande ganho de performance.&lt;/p&gt;
&lt;p&gt;Pois então, vamos fazer um benchmark para comparar a performance do PHP 8.0 com e sem JIT.&lt;/p&gt;
&lt;p&gt;No repositório &lt;a target="_blank" href="https://github.com/sschonss/jit-php-doc"&gt;php-jit-doc&lt;/a&gt; você encontra um script PHP que calcula um monte de coisa para deixar o processador bem ocupado.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Não vamos entrar em detalhes de escrita e padrões deste script, pois o foco é o JIT.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Vamos rodar o script sem JIT:&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./start.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;O resultado foi:&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Execution time: 6.2343468666077 seconds
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Encrypted: 46d37684d6032ef0167c00d29f3358d5a180438d3e8604e4c11728699d78fdb0a32284bfa8234ed59f69e7febd0d23bebab983211565582a98da8cb5c8800e42&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Agora vamos habilitar o JIT e rodar o script novamente:&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./start-jit.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;O resultado foi:&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Execution time: 3.292811870575 seconds
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Encrypted: 46d37684d6032ef0167c00d29f3358d5a180438d3e8604e4c11728699d78fdb0a32284bfa8234ed59f69e7febd0d23bebab983211565582a98da8cb5c8800e42&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Com o JIT habilitado, o script PHP rodou 3 segundos mais rápido. Isso é um ganho de performance muito considerável.&lt;/p&gt;
&lt;p&gt;Mas lembre-se, o JIT não é uma bala de prata. Ele pode não fazer muita diferença para scripts PHP que rodam na Web. Mas para scripts PHP que rodam na linha de comando, o JIT pode trazer um grande ganho de performance.&lt;/p&gt;
&lt;h2 id="heading-conclusao"&gt;&lt;strong&gt;Conclusão&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Esse foi um breve resumo sobre o JIT no PHP 8.0. Se você quiser saber mais sobre o JIT, recomendo a leitura da &lt;a target="_blank" href="https://www.php.net/manual/en/book.opcache.php"&gt;documentação oficial&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Trouxe somente exemplos básicos e didáticos para que você entenda o que é o JIT e como habilitá-lo. Acho que era importante trazer esse conteúdo para o perfil para que possamos falar sobre assuntos mais complexos e avançados.&lt;/p&gt;
&lt;p&gt;Se você gostou do conteúdo, deixe um comentário e compartilhe com seus amigos. Até a próxima!&lt;/p&gt;</description></item><item><title>Programação Paralela e Assíncrona com PHP</title><link>https://luizschons.com/pt-br/posts/programacao-paralela-e-assincrona-com-php/</link><pubDate>Thu, 25 Apr 2024 00:00:00 -0300</pubDate><guid>https://luizschons.com/pt-br/posts/programacao-paralela-e-assincrona-com-php/</guid><description>
&lt;p&gt;Photo by &lt;a target="_blank" href="https://unsplash.com/@benofthenorth?utm_source=medium&amp;utm_medium=referral"&gt;Ben Griffiths&lt;/a&gt; on &lt;a target="_blank" href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="heading-introducao"&gt;Introdução&lt;/h3&gt;
&lt;p&gt;PHP é uma linguagem de programação de propósito geral, amplamente utilizada para desenvolvimento web. No entanto, PHP também pode ser utilizado para desenvolvimento de aplicações desktop, scripts de automação, entre outros. Neste artigo, vamos explorar o uso de PHP para programação paralela e assíncrona.&lt;/p&gt;
&lt;h3 id="heading-programacao-paralela"&gt;Programação Paralela&lt;/h3&gt;
&lt;p&gt;Programação paralela é um paradigma de programação que consiste em dividir um problema em partes menores que podem ser executadas simultaneamente. Em PHP, a programação paralela pode ser feita utilizando a extensão &lt;a target="_blank" href="https://www.php.net/manual/en/book.parallel.php"&gt;parallel&lt;/a&gt; ou a extensão &lt;a target="_blank" href="https://www.php.net/manual/en/book.pthreads.php"&gt;pthreads&lt;/a&gt;, que permite a criação de threads em PHP.&lt;/p&gt;
&lt;h4 id="heading-mas-voce-sabe-o-que-e-uma-thread"&gt;Mas você sabe o que é uma thread?&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Uma thread é uma unidade básica de processamento que pode ser executada de forma independente. Em um programa paralelo, várias threads podem ser executadas simultaneamente, o que pode resultar em um aumento significativo de desempenho.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Quando você compra um processador com múltiplos núcleos, você está comprando a capacidade de executar várias threads simultaneamente. No entanto, para aproveitar ao máximo essa capacidade, é necessário que o software seja desenvolvido de forma a utilizar esses recursos de forma eficiente.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="heading-exemplo-de-programacao-paralela-em-php"&gt;Exemplo de Programação Paralela em PHP&lt;/h4&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="nx"&gt;php&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;parallel\run&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DataProcessor&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$formattedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;formatData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$excel_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;generateExcel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$formattedData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;sendEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$excel_file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$processor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DataProcessor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$parallelResult1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$processor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$processor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$parallelResult2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$processor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;No exemplo acima, estamos utilizando a extensão parallel para executar o método &lt;code&gt;process&lt;/code&gt; da classe &lt;code&gt;DataProcessor&lt;/code&gt; em paralelo. Isso significa que o método será executado em uma thread separada, o que pode resultar em um aumento de desempenho.&lt;/p&gt;
&lt;p&gt;Isso não é bala de prata, e nem sempre é a melhor solução para todos os problemas. No entanto, em alguns casos, a programação paralela pode ser uma forma eficiente de melhorar o desempenho de uma aplicação.&lt;/p&gt;
&lt;p&gt;O exemplo acima é bastante simplificado, mas ilustra como a programação paralela pode ser utilizada em PHP. Para obter mais informações sobre a extensão parallel, consulte a &lt;a target="_blank" href="https://www.php.net/manual/en/book.parallel.php"&gt;documentação oficial&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Aqui está uma imagem de um exemplo de programação paralela em PHP:&lt;/p&gt;
&lt;p&gt;&lt;img width="522" height="327" loading="lazy" decoding="async" src="https://luizschons.com/images/posts/programacao-paralela-e-assincrona-com-php/e7563efd-e150-4fc2-a5d1-758f6bb59a65.webp" alt="Diagrama da programação paralela: a thread principal inicia as threads A, B e C, que rodam ao mesmo tempo" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Imagem ilustrativa de um exemplo de programação paralela retirada da internet.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Perceba que a programação paralela é diferente da programação assíncrona. Na programação paralela, várias threads são executadas simultaneamente, enquanto na programação assíncrona, várias tarefas podem ser executadas de forma concorrente, mas não necessariamente simultaneamente.&lt;/p&gt;
&lt;h3 id="heading-programacao-assincrona"&gt;Programação Assíncrona&lt;/h3&gt;
&lt;p&gt;Programação assíncrona é um paradigma de programação que consiste em executar tarefas de forma concorrente, sem a necessidade de esperar que uma tarefa seja concluída para iniciar outra. Em PHP, a programação assíncrona pode ser feita utilizando a extensão &lt;a target="_blank" href="https://www.swoole.co.uk/"&gt;swoole&lt;/a&gt;, que permite a criação de servidores web assíncronos em PHP.&lt;/p&gt;
&lt;h4 id="heading-mas-voce-sabe-o-que-e-um-servidor-web-assincrono"&gt;Mas você sabe o que é um servidor web assíncrono?&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Um servidor web assíncrono é um servidor que pode lidar com várias requisições simultaneamente, sem a necessidade de criar uma nova thread para cada requisição. Isso permite que o servidor seja mais eficiente e possa lidar com um grande número de requisições de forma concorrente.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Você pode achar o termo “servidor autocontido” em alguns lugares, mas a ideia é a mesma: um servidor que pode lidar com várias requisições simultaneamente, sem a necessidade de criar uma nova thread para cada requisição.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="heading-exemplo-de-programacao-assincrona-em-php"&gt;Exemplo de Programação Assíncrona em PHP&lt;/h4&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Swoole\Http\Server&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;0.0.0.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9501&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$server&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;start&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Server&lt;/span&gt; &lt;span class="nv"&gt;$server&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Server started at http://&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$server&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$server&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$server&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;rawContent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$response&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Received data: &lt;/span&gt;&lt;span class="si"&gt;$data&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$server&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;No exemplo acima, estamos utilizando a extensão swoole para criar um servidor web assíncrono em PHP. O servidor irá escutar na porta 9501 e responder a todas as requisições com uma mensagem contendo os dados recebidos.&lt;/p&gt;
&lt;p&gt;Esse exemplo é bastante simplificado, mas ilustra como a programação assíncrona pode ser utilizada em PHP. Para obter mais informações sobre a extensão swoole, consulte a &lt;a target="_blank" href="https://www.swoole.co.uk/"&gt;documentação oficial&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Aqui está uma imagem de um exemplo de programação assíncrona:&lt;/p&gt;
&lt;p&gt;&lt;img width="612" height="480" loading="lazy" decoding="async" src="https://luizschons.com/images/posts/programacao-paralela-e-assincrona-com-php/554adf54-7f19-4abf-bea2-aad9a2b23333.webp" alt="Diagrama de sequência da programação assíncrona: um processo dispara várias requisições por uma thread e recebe as respostas fora de ordem" /&gt;&lt;/p&gt;
&lt;p&gt;Imagem ilustrativa de um exemplo de programação assíncrona retirada da internet.&lt;/p&gt;
&lt;h3 id="heading-ciclo-de-vida-de-uma-requisicao-no-php-fpm"&gt;Ciclo de Vida de uma Requisição no PHP-FPM&lt;/h3&gt;
&lt;p&gt;Quando uma requisição é feita a um servidor web PHP, como o PHP-FPM, o servidor passa por várias etapas para processar a requisição e retornar uma resposta ao cliente. O ciclo de vida de uma requisição no PHP-FPM pode ser dividido em várias etapas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Recebimento da Requisição:&lt;/strong&gt; O servidor web (Apache, Nginx, etc.) recebe a requisição do cliente e a encaminha para o PHP-FPM.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pool de Processos:&lt;/strong&gt; O PHP-FPM mantém um pool de processos PHP pré-carregados para processar as requisições. Quando uma requisição é recebida, o PHP-FPM escolhe um processo disponível para processar a requisição.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Autoload:&lt;/strong&gt; O PHP-FPM carrega os arquivos necessários para processar a requisição, incluindo as classes e funções utilizadas no script PHP. As classes e funções são carregadas automaticamente pelo PHP, de acordo com as regras de autoload definidas no arquivo &lt;code&gt;composer.json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Análise e Compilação:&lt;/strong&gt; O PHP analisa o script PHP e compila o código em uma forma que pode ser executada pelo interpretador PHP.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Execução do Script:&lt;/strong&gt; O PHP executa o script PHP, processando as instruções e gerando a saída da requisição.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gerar Resposta:&lt;/strong&gt; O PHP-FPM gera a resposta da requisição, incluindo o cabeçalho HTTP e o corpo da resposta.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Envio da Resposta:&lt;/strong&gt; O PHP-FPM envia a resposta ao servidor web, que a encaminha de volta ao cliente.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Encerramento do Processo:&lt;/strong&gt; Após enviar a resposta, o processo PHP é encerrado e retorna ao pool de processos disponíveis para processar novas requisições.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;O ciclo de vida de uma requisição no PHP-FPM pode variar dependendo da configuração do servidor web e do PHP-FPM. No entanto, essas etapas são comuns na maioria dos servidores web PHP.&lt;/p&gt;
&lt;h3 id="heading-ciclo-de-vida-de-uma-requisicao-no-swoole"&gt;Ciclo de Vida de uma Requisição no Swoole&lt;/h3&gt;
&lt;p&gt;Quando uma requisição é feita a um servidor web assíncrono PHP, como o Swoole, o servidor passa por várias etapas para processar a requisição e retornar uma resposta ao cliente. O ciclo de vida de uma requisição no Swoole pode ser dividido em várias etapas:&lt;/p&gt;
&lt;p&gt;O início do ciclo de vida de uma requisição no Swoole começa com a inicialização do servidor Swoole e a configuração do script PHP que será executado para processar as requisições. O servidor Swoole escuta em uma porta específica e aguarda a chegada de requisições.&lt;/p&gt;
&lt;p&gt;Nesse ponto, o servidor já está com o autoload configurado, as classes e funções necessárias já estão carregadas e o script PHP está pronto para processar as requisições.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Recebimento da Requisição:&lt;/strong&gt; Quando uma requisição é feita ao servidor Swoole, o servidor recebe a requisição e a encaminha para o script PHP configurado para processar a requisição.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Processamento da Requisição:&lt;/strong&gt; O script PHP processa a requisição, executando as instruções necessárias para gerar a resposta da requisição.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Análise e Compilação:&lt;/strong&gt; O PHP analisa o script PHP e compila o código em uma forma que pode ser executada pelo interpretador PHP.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Execução do Script:&lt;/strong&gt; O PHP executa o script PHP, processando as instruções e gerando a saída da requisição.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gerar Resposta:&lt;/strong&gt; O script PHP gera a resposta da requisição, incluindo o cabeçalho HTTP e o corpo da resposta.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Envio da Resposta:&lt;/strong&gt; O servidor Swoole envia a resposta ao cliente, encerrando o ciclo de vida da requisição.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;E nesse momento, o servidor Swoole está pronto para processar novas requisições, mantendo um pool de processos PHP disponíveis para processar as requisições de forma assíncrona.&lt;/p&gt;
&lt;p&gt;A diferença entre o ciclo de vida de uma requisição no PHP-FPM e no Swoole está na forma como o servidor PHP é inicializado e como as requisições são processadas. No PHP-FPM, o servidor PHP é inicializado para processar uma única requisição de cada vez, enquanto no Swoole, o servidor PHP é inicializado para processar várias requisições de forma assíncrona.&lt;/p&gt;
&lt;h3 id="heading-conclusao"&gt;Conclusão&lt;/h3&gt;
&lt;p&gt;Neste artigo, exploramos o uso de PHP para programação paralela e assíncrona. A programação paralela e assíncrona são técnicas de programação que podem ser utilizadas para melhorar o desempenho de uma aplicação e lidar com um grande número de requisições de forma eficiente.&lt;/p&gt;
&lt;p&gt;Nem tudo é regra, e nem sempre a programação paralela ou assíncrona é a melhor solução para um problema. No entanto, é sempre bom conhecer as diferentes técnicas de programação disponíveis e saber quando utilizá-las de forma eficiente.&lt;/p&gt;
&lt;p&gt;Espero que este artigo tenha sido útil e que você tenha aprendido algo novo sobre programação paralela e assíncrona em PHP. Espero que futuramente eu consiga fazer um artigo mais detalhado sobre cada uma dessas técnicas, com exemplos mais complexos e detalhados.&lt;/p&gt;
&lt;p&gt;Qualquer dúvida, correção ou sugestão, fique à vontade para entrar em contato. Obrigado por ler até aqui!&lt;/p&gt;
&lt;h3 id="heading-referencias"&gt;Referências&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a target="_blank" href="https://www.php.net/manual/en/book.parallel.php"&gt;PHP Parallel Extension&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a target="_blank" href="https://www.php.net/manual/en/book.pthreads.php"&gt;PHP pthreads Extension&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a target="_blank" href="https://www.swoole.co.uk/"&gt;Swoole Extension&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a target="_blank" href="https://www.php.net/manual/en/install.fpm.php"&gt;PHP-FPM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a target="_blank" href="https://www.php.net/manual/en/language.oop5.autoload.php"&gt;PHP Autoload&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a target="_blank" href="https://getcomposer.org/"&gt;PHP Composer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a target="_blank" href="https://www.php-fig.org/psr/"&gt;PHP PSR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a target="_blank" href="https://fastcgi-archives.github.io/"&gt;FastCGI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="heading-autor"&gt;Autor&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a target="_blank" href="https://linkedin.com/in/luiz-schons"&gt;Luiz Schons&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>