<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Luiz Schons – Performance</title><link>https://luizschons.com/tags/performance/</link><description>Recent content in Performance on Luiz Schons</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Tue, 28 May 2024 00:00:00 -0300</lastBuildDate><atom:link href="https://luizschons.com/tags/performance/index.xml" rel="self" type="application/rss+xml"/><item><title>JIT (Just in Time) — PHP</title><link>https://luizschons.com/posts/jit-just-in-time-in-php/</link><pubDate>Tue, 28 May 2024 00:00:00 -0300</pubDate><guid>https://luizschons.com/posts/jit-just-in-time-in-php/</guid><description>
&lt;p&gt;If you haven't upgraded to PHP 8.0 or later yet, it's time to do it. PHP 8.0 was released on November 26, 2020 and brought the JIT (Just In Time) compiler, which is what we are going to talk about today.&lt;/p&gt;
&lt;h2 id="heading-opcode"&gt;Opcode&lt;/h2&gt;
&lt;p&gt;When you run a PHP script, PHP compiles it into an intermediate code called opcode (PHP Opcode). The opcode is then executed by the Zend virtual machine.&lt;/p&gt;
&lt;p&gt;Here is an example of PHP code and its opcode:&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;Opcode:&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;Basically, opcode is a sequence of instructions that the Zend virtual machine executes.&lt;/p&gt;
&lt;h2 id="heading-jit"&gt;&lt;strong&gt;JIT&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;So where does the JIT come in? The JIT is a compiler that compiles opcode into native machine code. In other words, it turns opcode into machine code that the CPU can execute directly.&lt;/p&gt;
&lt;p&gt;This way, we no longer use the Zend virtual machine to execute the opcode, but the native machine code generated by the JIT.&lt;/p&gt;
&lt;h2 id="heading-enabling-the-jit"&gt;&lt;strong&gt;Enabling the JIT&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;The JIT is not enabled by default. To enable it, you need a few extra steps.&lt;/p&gt;
&lt;p&gt;First, you need to install the &lt;code&gt;opcache&lt;/code&gt; extension:&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;Then, you need to enable the JIT in the PHP configuration file (&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;Here we are enabling the JIT and setting the JIT buffer size to 100 MB. The JIT can run in two modes: &lt;code&gt;tracing&lt;/code&gt; and &lt;code&gt;function&lt;/code&gt;. The &lt;code&gt;tracing&lt;/code&gt; mode is the default and is faster, while the &lt;code&gt;function&lt;/code&gt; mode is more precise.&lt;/p&gt;
&lt;p&gt;To better understand the difference between the &lt;code&gt;tracing&lt;/code&gt; and &lt;code&gt;function&lt;/code&gt; modes, I recommend reading the &lt;a target="_blank" href="https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.jit"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finally, we enable the JIT for the command line (&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;If you run PHP on the web, the JIT may not make much difference. But if you run PHP scripts on the command line, the JIT can bring a big performance gain.&lt;/p&gt;
&lt;p&gt;So let's run a benchmark to compare PHP 8.0 performance with and without the JIT.&lt;/p&gt;
&lt;p&gt;In the &lt;a target="_blank" href="https://github.com/sschonss/jit-php-doc"&gt;php-jit-doc&lt;/a&gt; repository you will find a PHP script that calculates a lot of things to keep the processor busy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;We won't go into the details of how this script is written or its patterns, since the focus is the JIT.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let's run the script without the 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;The result was:&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;Now let's enable the JIT and run the script again:&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;The result was:&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;With the JIT enabled, the PHP script ran 3 seconds faster. That is a very significant performance gain.&lt;/p&gt;
&lt;p&gt;But remember, the JIT is not a silver bullet. It may not make much difference for PHP scripts that run on the web. For PHP scripts that run on the command line, however, the JIT can bring a big performance gain.&lt;/p&gt;
&lt;h2 id="heading-conclusion"&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;This was a brief overview of the JIT in PHP 8.0. If you want to learn more about it, I recommend reading the &lt;a target="_blank" href="https://www.php.net/manual/en/book.opcache.php"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I only brought basic, teaching examples so you can understand what the JIT is and how to enable it. I think it was important to cover this first so we can talk about more complex and advanced topics.&lt;/p&gt;
&lt;p&gt;If you liked this content, leave a comment and share it with your friends. See you next time!&lt;/p&gt;</description></item><item><title>Parallel and Asynchronous Programming with PHP</title><link>https://luizschons.com/posts/parallel-and-asynchronous-programming-with-php/</link><pubDate>Thu, 25 Apr 2024 00:00:00 -0300</pubDate><guid>https://luizschons.com/posts/parallel-and-asynchronous-programming-with-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-introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;PHP is a general-purpose programming language widely used for web development. However, PHP can also be used for desktop applications, automation scripts and more. In this article, we will explore using PHP for parallel and asynchronous programming.&lt;/p&gt;
&lt;h3 id="heading-parallel-programming"&gt;Parallel Programming&lt;/h3&gt;
&lt;p&gt;Parallel programming is a programming paradigm that splits a problem into smaller parts that can run at the same time. In PHP, parallel programming can be done with the &lt;a target="_blank" href="https://www.php.net/manual/en/book.parallel.php"&gt;parallel&lt;/a&gt; extension or the &lt;a target="_blank" href="https://www.php.net/manual/en/book.pthreads.php"&gt;pthreads&lt;/a&gt; extension, which let you create threads in PHP.&lt;/p&gt;
&lt;h4 id="heading-but-do-you-know-what-a-thread-is"&gt;But do you know what a thread is?&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A thread is a basic unit of processing that can run independently. In a parallel program, several threads can run at the same time, which can result in a significant performance boost.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;When you buy a multi-core processor, you are buying the ability to run several threads at the same time. However, to take full advantage of that, the software has to be built to use those resources efficiently.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="heading-parallel-programming-example-in-php"&gt;Parallel Programming Example in 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;In the example above, we use the parallel extension to run the &lt;code&gt;process&lt;/code&gt; method of the &lt;code&gt;DataProcessor&lt;/code&gt; class in parallel. This means the method runs in a separate thread, which can result in better performance.&lt;/p&gt;
&lt;p&gt;This is not a silver bullet, and it is not always the best solution for every problem. In some cases, however, parallel programming can be an efficient way to improve an application's performance.&lt;/p&gt;
&lt;p&gt;The example above is quite simplified, but it shows how parallel programming can be used in PHP. For more information about the parallel extension, see the &lt;a target="_blank" href="https://www.php.net/manual/en/book.parallel.php"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here is an image illustrating parallel programming:&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="Parallel programming diagram: the main thread starts threads A, B and C, which run at the same time" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Illustration of parallel programming, taken from the internet.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Note that parallel programming is different from asynchronous programming. In parallel programming, several threads run at the same time, while in asynchronous programming several tasks can run concurrently, but not necessarily at the same time.&lt;/p&gt;
&lt;h3 id="heading-asynchronous-programming"&gt;Asynchronous Programming&lt;/h3&gt;
&lt;p&gt;Asynchronous programming is a programming paradigm that runs tasks concurrently, without waiting for one task to finish before starting another. In PHP, asynchronous programming can be done with the &lt;a target="_blank" href="https://www.swoole.co.uk/"&gt;swoole&lt;/a&gt; extension, which lets you create asynchronous web servers in PHP.&lt;/p&gt;
&lt;h4 id="heading-but-do-you-know-what-an-asynchronous-web-server-is"&gt;But do you know what an asynchronous web server is?&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;An asynchronous web server is a server that can handle several requests at the same time without creating a new thread for each one. This makes the server more efficient and able to handle a large number of requests concurrently.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;You may see the term “self-contained server” in some places, but the idea is the same: a server that can handle several requests at the same time without creating a new thread for each one.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="heading-asynchronous-programming-example-in-php"&gt;Asynchronous Programming Example in 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;In the example above, we use the swoole extension to create an asynchronous web server in PHP. The server listens on port 9501 and answers every request with a message containing the data it received.&lt;/p&gt;
&lt;p&gt;This example is quite simplified, but it shows how asynchronous programming can be used in PHP. For more information about the swoole extension, see the &lt;a target="_blank" href="https://www.swoole.co.uk/"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here is an image illustrating asynchronous programming:&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="Sequence diagram of asynchronous programming: a process fires several requests through a thread and gets the responses out of order" /&gt;&lt;/p&gt;
&lt;p&gt;Illustration of asynchronous programming, taken from the internet.&lt;/p&gt;
&lt;h3 id="heading-request-lifecycle-in-php-fpm"&gt;Request Lifecycle in PHP-FPM&lt;/h3&gt;
&lt;p&gt;When a request is made to a PHP web server such as PHP-FPM, the server goes through several steps to process it and return a response to the client. The lifecycle of a request in PHP-FPM can be split into these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Receiving the Request:&lt;/strong&gt; The web server (Apache, Nginx, etc.) receives the client's request and forwards it to PHP-FPM.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Process Pool:&lt;/strong&gt; PHP-FPM keeps a pool of preloaded PHP processes to handle requests. When a request arrives, PHP-FPM picks an available process to handle it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Autoload:&lt;/strong&gt; PHP-FPM loads the files needed to process the request, including the classes and functions used in the PHP script. Classes and functions are loaded automatically by PHP, following the autoload rules defined in &lt;code&gt;composer.json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parsing and Compilation:&lt;/strong&gt; PHP parses the PHP script and compiles the code into a form the PHP interpreter can execute.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Script Execution:&lt;/strong&gt; PHP executes the script, processing its instructions and generating the request's output.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Building the Response:&lt;/strong&gt; PHP-FPM builds the response, including the HTTP headers and the response body.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sending the Response:&lt;/strong&gt; PHP-FPM sends the response to the web server, which forwards it back to the client.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ending the Process:&lt;/strong&gt; After sending the response, the PHP process finishes and returns to the pool of processes available for new requests.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The lifecycle of a request in PHP-FPM can vary depending on the web server and PHP-FPM configuration. However, these steps are common to most PHP web servers.&lt;/p&gt;
&lt;h3 id="heading-request-lifecycle-in-swoole"&gt;Request Lifecycle in Swoole&lt;/h3&gt;
&lt;p&gt;When a request is made to an asynchronous PHP web server such as Swoole, the server goes through several steps to process it and return a response to the client. The lifecycle of a request in Swoole can be split into these steps:&lt;/p&gt;
&lt;p&gt;The lifecycle starts when the Swoole server boots and sets up the PHP script that will handle requests. The Swoole server listens on a specific port and waits for requests to arrive.&lt;/p&gt;
&lt;p&gt;At this point, the server already has autoload configured, the required classes and functions are already loaded, and the PHP script is ready to handle requests.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Receiving the Request:&lt;/strong&gt; When a request reaches the Swoole server, the server receives it and passes it to the PHP script configured to handle it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Processing the Request:&lt;/strong&gt; The PHP script processes the request, running the instructions needed to generate the response.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parsing and Compilation:&lt;/strong&gt; PHP parses the PHP script and compiles the code into a form the PHP interpreter can execute.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Script Execution:&lt;/strong&gt; PHP executes the script, processing its instructions and generating the request's output.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Building the Response:&lt;/strong&gt; The PHP script builds the response, including the HTTP headers and the response body.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sending the Response:&lt;/strong&gt; The Swoole server sends the response to the client, ending the request's lifecycle.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;At that point, the Swoole server is ready for new requests, keeping a pool of PHP processes available to handle them asynchronously.&lt;/p&gt;
&lt;p&gt;The difference between the request lifecycle in PHP-FPM and in Swoole lies in how the PHP server boots and how requests are processed. In PHP-FPM, each PHP process is set up to handle one request at a time, while in Swoole the PHP server is set up to handle many requests asynchronously.&lt;/p&gt;
&lt;h3 id="heading-conclusion"&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;In this article, we explored using PHP for parallel and asynchronous programming. Parallel and asynchronous programming are techniques that can improve an application's performance and handle a large number of requests efficiently.&lt;/p&gt;
&lt;p&gt;There are no hard rules, and parallel or asynchronous programming is not always the best solution to a problem. Still, it is always good to know the different techniques available and when to use them well.&lt;/p&gt;
&lt;p&gt;I hope this article was useful and that you learned something new about parallel and asynchronous programming in PHP. In the future, I hope to write a more detailed article about each of these techniques, with more complex examples.&lt;/p&gt;
&lt;p&gt;If you have any questions, corrections or suggestions, feel free to reach out. Thanks for reading this far!&lt;/p&gt;
&lt;h3 id="heading-references"&gt;References&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-author"&gt;Author&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>