{"data":{"markdownRemark":{"frontmatter":{"title":"Разбираем, что под капотом у PHP циклов","date":"25 September 2020","path":"/razbiraem-chto-pod-kapotom-u-php-ciklov/","author":null,"excerpt":"В этой статье мы посмотрим, что находится под капотом у PHP циклов, а точнее сравним их опкоды.","tags":["PHP","Под капотом"],"coverImage":{"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAMFAQT/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGJqWnWWg//xAAaEAACAgMAAAAAAAAAAAAAAAABAgMRABMi/9oACAEBAAEFAuLQAs8IvFJuNBr/AP/EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABoQAAICAwAAAAAAAAAAAAAAAAABAiEQUXH/2gAIAQEABj8CtMWisx4f/8QAGRABAQEAAwAAAAAAAAAAAAAAAREAECFR/9oACAEBAAE/IRSQHg6tMrRFqJwYR3YLY3//2gAMAwEAAgADAAAAECMP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAHBABAAMBAAMBAAAAAAAAAAAAAQARITFBYXGR/9oACAEBAAE/EFAtU97lt8+RAzN5eRwrKt+fyCnGImg2TflYUatqf//Z","aspectRatio":1.5,"src":"/static/e16f9dccf792794dbe39f3c76864ff34/b4295/alen-jacob-wdxb9OOMQOs-unsplash.jpg","srcSet":"/static/e16f9dccf792794dbe39f3c76864ff34/127d5/alen-jacob-wdxb9OOMQOs-unsplash.jpg 200w,\n/static/e16f9dccf792794dbe39f3c76864ff34/7ef6a/alen-jacob-wdxb9OOMQOs-unsplash.jpg 400w,\n/static/e16f9dccf792794dbe39f3c76864ff34/b4295/alen-jacob-wdxb9OOMQOs-unsplash.jpg 800w,\n/static/e16f9dccf792794dbe39f3c76864ff34/5501e/alen-jacob-wdxb9OOMQOs-unsplash.jpg 1200w,\n/static/e16f9dccf792794dbe39f3c76864ff34/9f4ef/alen-jacob-wdxb9OOMQOs-unsplash.jpg 1600w,\n/static/e16f9dccf792794dbe39f3c76864ff34/98cf4/alen-jacob-wdxb9OOMQOs-unsplash.jpg 2400w,\n/static/e16f9dccf792794dbe39f3c76864ff34/6b018/alen-jacob-wdxb9OOMQOs-unsplash.jpg 5472w","sizes":"(max-width: 800px) 100vw, 800px"}}}},"id":"eac69917-577e-52a4-9114-4d3b201f2a20","html":"<p>В этой статье мы посмотрим, что находится под капотом у PHP циклов, а точнее сравним их опкоды.</p>\n<p>А вот начнём с самого НЕ часто используемого вида циклов</p>\n<h3>for</h3>\n<div class=\"gatsby-highlight\" data-language=\"php\"><pre class=\"language-php\"><code class=\"language-php\"><span class=\"token php language-php\"><span class=\"token delimiter important\">&lt;?php</span>\n\n<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span> <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> <span class=\"token variable\">$i</span> <span class=\"token operator\">&lt;</span> <span class=\"token number\">10</span><span class=\"token punctuation\">;</span> <span class=\"token variable\">$i</span><span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token punctuation\">}</span></span></code></pre></div>\n<p>Для вытаскивания опкодов изначально хотел использовать расширение vld.\nНо как оказалось выводит оно не правильный опкод, по этому обойдёмся стандартными методами php 7.</p>\n<p>Сейчас приведу полный вывод (до оптимизации). В дальнейшем только те части, которые нас интересуют.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">➜  ~ php -d opcache.opt_debug_level<span class=\"token operator\">=</span>0x10000 -d opcache.enable_cli<span class=\"token operator\">=</span>1 for.php\n\n<span class=\"token variable\">$_main</span><span class=\"token keyword\">:</span> <span class=\"token punctuation\">;</span> <span class=\"token punctuation\">(</span>lines<span class=\"token operator\">=</span>7, args<span class=\"token operator\">=</span>0, vars<span class=\"token operator\">=</span>1, tmps<span class=\"token operator\">=</span>3<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">;</span> <span class=\"token punctuation\">(</span>before optimizer<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">;</span> /home/la/experiment/for.php:1-4\nL0 <span class=\"token punctuation\">(</span>3<span class=\"token punctuation\">)</span>:     ASSIGN CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span> int<span class=\"token punctuation\">(</span>0<span class=\"token punctuation\">)</span>\nL1 <span class=\"token punctuation\">(</span>3<span class=\"token punctuation\">)</span>:     JMP L4\nL2 <span class=\"token punctuation\">(</span>3<span class=\"token punctuation\">)</span>:     T2 <span class=\"token operator\">=</span> POST_INC CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span>\nL3 <span class=\"token punctuation\">(</span>3<span class=\"token punctuation\">)</span>:     FREE T2\nL4 <span class=\"token punctuation\">(</span>3<span class=\"token punctuation\">)</span>:     T3 <span class=\"token operator\">=</span> IS_SMALLER CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span> int<span class=\"token punctuation\">(</span>10<span class=\"token punctuation\">)</span>\nL5 <span class=\"token punctuation\">(</span>3<span class=\"token punctuation\">)</span>:     JMPNZ T3 L2\nL6 <span class=\"token punctuation\">(</span>4<span class=\"token punctuation\">)</span>:     RETURN int<span class=\"token punctuation\">(</span>1<span class=\"token punctuation\">)</span></code></pre></div>\n<p>Описание всех опкодов есть на <a href=\"https://www.php.net/manual/en/internals2.opcodes.list.php\">офф сайте</a>.</p>\n<p>Мои эксперименты происходят на версии 7.4.3</p>\n<p>Разберём что происходит? На самом деле абсолютно ничего сверхестественного.\nПлотно разберём только первый цикл, остальные думаю будут понятно, в конце концов тут ничего сложного.</p>\n<p>Итак, строка 0<br>\nL0: Присвоение в <code class=\"language-text\">CV0</code> числа 0<br>\nТ.е. если бы мы написали в коде $i = 3, и $i была не первая переменная, а скажем вторая то строка в опкодах выглядела бы примерно так</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">L0 <span class=\"token punctuation\">(</span>3<span class=\"token punctuation\">)</span>:     ASSIGN CV1<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span> int<span class=\"token punctuation\">(</span>3<span class=\"token punctuation\">)</span></code></pre></div>\n<p>L1: Прыжок (<code class=\"language-text\">JMP</code>) на строку 4 (<code class=\"language-text\">L4</code>)<br>\nL4: Переменная в <code class=\"language-text\">CV0</code> меньше 10, если да то возвращает в <code class=\"language-text\">T3</code> 1 иначе 0<br>\nL5: А эта строка принимает то что возвратила предыдущая и если не 0 (JMP<strong>NZ</strong>, т.е jump if not zero) то прыжок на строку <code class=\"language-text\">L2</code>.<br>\nL2: <code class=\"language-text\">POST_INC</code> - INCрементируем то что лежит в <code class=\"language-text\">CV0</code> и возвращаем в <code class=\"language-text\">T2</code><br>\nL3: Так как не используем результат больше нигде, то освобождаем память выделенную для <code class=\"language-text\">T2</code><br>\nДальше цикл повторяется, пока в строке <code class=\"language-text\">L4</code> <code class=\"language-text\">IS_SMALLER</code> не вернёт 0. Как только это случится,<br>\n<code class=\"language-text\">JPNNZ</code> не отработает и мы просто переёдем на строку <code class=\"language-text\">L6</code> c которой мы выйдем возвратив 1</p>\n<p>Ничего сложного, правда?</p>\n<h3>WHILE</h3>\n<p>Давайте теперь сравним с циклом  while</p>\n<div class=\"gatsby-highlight\" data-language=\"php\"><pre class=\"language-php\"><code class=\"language-php\"><span class=\"token php language-php\"><span class=\"token delimiter important\">&lt;?php</span>\n\n<span class=\"token variable\">$i</span> <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span> <span class=\"token operator\">&lt;</span> <span class=\"token number\">10</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token variable\">$i</span><span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></span></code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">L0 <span class=\"token punctuation\">(</span>3<span class=\"token punctuation\">)</span>:     ASSIGN CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span> int<span class=\"token punctuation\">(</span>0<span class=\"token punctuation\">)</span>\nL1 <span class=\"token punctuation\">(</span>4<span class=\"token punctuation\">)</span>:     JMP L4\nL2 <span class=\"token punctuation\">(</span>5<span class=\"token punctuation\">)</span>:     T2 <span class=\"token operator\">=</span> POST_INC CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span>\nL3 <span class=\"token punctuation\">(</span>5<span class=\"token punctuation\">)</span>:     FREE T2\nL4 <span class=\"token punctuation\">(</span>4<span class=\"token punctuation\">)</span>:     T3 <span class=\"token operator\">=</span> IS_SMALLER CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span> int<span class=\"token punctuation\">(</span>2<span class=\"token punctuation\">)</span>\nL5 <span class=\"token punctuation\">(</span>4<span class=\"token punctuation\">)</span>:     JMPNZ T3 L2\nL6 <span class=\"token punctuation\">(</span>7<span class=\"token punctuation\">)</span>:     RETURN int<span class=\"token punctuation\">(</span>1<span class=\"token punctuation\">)</span></code></pre></div>\n<p>Выглядит знакомо? Да в точности так же!</p>\n<p>Единственное, что можно заметить, это то что в скобках указаны другие строки. В варианте с for почти всё происходит в строке 3. Если бы в первом примере использовали цикл for так:</p>\n<div class=\"gatsby-highlight\" data-language=\"php\"><pre class=\"language-php\"><code class=\"language-php\"><span class=\"token variable\">$i</span> <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">;</span> <span class=\"token variable\">$i</span> <span class=\"token operator\">&lt;</span> <span class=\"token number\">10</span><span class=\"token punctuation\">;</span> <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token variable\">$i</span><span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>То по опкодам вы бы низачто не поняли, for это или while =) Он выглядел бы в точности так же как while.</p>\n<h3>do->while</h3>\n<div class=\"gatsby-highlight\" data-language=\"php\"><pre class=\"language-php\"><code class=\"language-php\"><span class=\"token php language-php\"><span class=\"token delimiter important\">&lt;?php</span>\n\n<span class=\"token variable\">$i</span> <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">do</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token variable\">$i</span><span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span> <span class=\"token keyword\">while</span><span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span> <span class=\"token operator\">&lt;</span> <span class=\"token number\">10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span></code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">L0 <span class=\"token punctuation\">(</span>3<span class=\"token punctuation\">)</span>:     ASSIGN CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span> int<span class=\"token punctuation\">(</span>0<span class=\"token punctuation\">)</span>\nL1 <span class=\"token punctuation\">(</span>5<span class=\"token punctuation\">)</span>:     T2 <span class=\"token operator\">=</span> POST_INC CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span>\nL2 <span class=\"token punctuation\">(</span>5<span class=\"token punctuation\">)</span>:     FREE T2\nL3 <span class=\"token punctuation\">(</span>6<span class=\"token punctuation\">)</span>:     T3 <span class=\"token operator\">=</span> IS_SMALLER CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span> int<span class=\"token punctuation\">(</span>10<span class=\"token punctuation\">)</span>\nL4 <span class=\"token punctuation\">(</span>6<span class=\"token punctuation\">)</span>:     JMPNZ T3 L1\nL5 <span class=\"token punctuation\">(</span>6<span class=\"token punctuation\">)</span>:     RETURN int<span class=\"token punctuation\">(</span>1<span class=\"token punctuation\">)</span></code></pre></div>\n<p>Обратите внимание, в этом варианте нет прыжка на условие, а сначала выполняется тело цикла, собственно как и должно быть) В остальном всё точно так же.</p>\n<p>В php 4 появился новый вид цикла, специально для переборки массива</p>\n<h3>foreach</h3>\n<div class=\"gatsby-highlight\" data-language=\"php\"><pre class=\"language-php\"><code class=\"language-php\"><span class=\"token php language-php\"><span class=\"token delimiter important\">&lt;?php</span>\n\n<span class=\"token variable\">$i</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">foreach</span> <span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span> <span class=\"token keyword\">as</span> <span class=\"token variable\">$value</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token punctuation\">}</span></span></code></pre></div>\n<p>Он конечно же сильно отличается</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">L0 <span class=\"token punctuation\">(</span>3<span class=\"token punctuation\">)</span>:     ASSIGN CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span> array<span class=\"token punctuation\">(</span><span class=\"token punctuation\">..</span>.<span class=\"token punctuation\">)</span>\nL1 <span class=\"token punctuation\">(</span>4<span class=\"token punctuation\">)</span>:     V3 <span class=\"token operator\">=</span> FE_RESET_R CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span> L4\nL2 <span class=\"token punctuation\">(</span>4<span class=\"token punctuation\">)</span>:     FE_FETCH_R V3 CV1<span class=\"token punctuation\">(</span><span class=\"token variable\">$value</span><span class=\"token punctuation\">)</span> L4\nL3 <span class=\"token punctuation\">(</span>4<span class=\"token punctuation\">)</span>:     JMP L2\nL4 <span class=\"token punctuation\">(</span>4<span class=\"token punctuation\">)</span>:     FE_FREE V3\nL5 <span class=\"token punctuation\">(</span>5<span class=\"token punctuation\">)</span>:     RETURN int<span class=\"token punctuation\">(</span>1<span class=\"token punctuation\">)</span>\nLIVE RANGES:\n        3: L2 - L4 <span class=\"token punctuation\">(</span>loop<span class=\"token punctuation\">)</span></code></pre></div>\n<p>L1: создаём итератор <code class=\"language-text\">V3</code> массива <code class=\"language-text\">CV0</code>. Если массив пуст, прыгаем на строку <code class=\"language-text\">L4</code><br>\nL2: делаем шаг итерации итератора <code class=\"language-text\">V3</code> извлекая значение в <code class=\"language-text\">CV1</code>. Если достигнули конец массива, прыгаем на строку <code class=\"language-text\">L4</code><br>\nL3: Прыгаем на строку <code class=\"language-text\">L2</code><br>\nЦикл будет повторяться пока в <code class=\"language-text\">V3</code> есть что извлекать. Как только достигнем конец, прыгаем на <code class=\"language-text\">L4</code><br>\nL4: Освобождаем <code class=\"language-text\">V3</code><br></p>\n<h3>goto (for fan)</h3>\n<p>Это конечно не цикл.<br>\nК тому же так не следует делать, goto плохая практика в плане понимания кода в целом, но под капотом не сильно что меняется по сравнению с другими циклами.<br>\nДавайте сделаем подобие do-while</p>\n<div class=\"gatsby-highlight\" data-language=\"php\"><pre class=\"language-php\"><code class=\"language-php\"><span class=\"token php language-php\"><span class=\"token delimiter important\">&lt;?php</span>\n\n<span class=\"token variable\">$i</span> <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\na<span class=\"token punctuation\">:</span>\n    <span class=\"token variable\">$i</span><span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span> <span class=\"token operator\">&lt;</span> <span class=\"token number\">10</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">goto</span> a<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></span></code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">L0 <span class=\"token punctuation\">(</span>3<span class=\"token punctuation\">)</span>:     ASSIGN CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span> int<span class=\"token punctuation\">(</span>0<span class=\"token punctuation\">)</span>\nL1 <span class=\"token punctuation\">(</span>5<span class=\"token punctuation\">)</span>:     T2 <span class=\"token operator\">=</span> POST_INC CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span>\nL2 <span class=\"token punctuation\">(</span>5<span class=\"token punctuation\">)</span>:     FREE T2\nL3 <span class=\"token punctuation\">(</span>6<span class=\"token punctuation\">)</span>:     T3 <span class=\"token operator\">=</span> IS_SMALLER CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span> int<span class=\"token punctuation\">(</span>10<span class=\"token punctuation\">)</span>\nL4 <span class=\"token punctuation\">(</span>6<span class=\"token punctuation\">)</span>:     JMPZ T3 L6\nL5 <span class=\"token punctuation\">(</span>7<span class=\"token punctuation\">)</span>:     JMP L1\nL6 <span class=\"token punctuation\">(</span>8<span class=\"token punctuation\">)</span>:     RETURN int<span class=\"token punctuation\">(</span>1<span class=\"token punctuation\">)</span></code></pre></div>\n<p>По сравнению с опкодами do-while, различия в двух строках: L4 &#x26;&#x26; L5</p>\n<p>L4: Прыжок на <code class=\"language-text\">L6</code> если в <code class=\"language-text\">T3</code> ноль<br>\nL5: Безусловный переход на <code class=\"language-text\">L1</code></p>\n<h3>Заключение</h3>\n<p>Это почти всё, что я хотел сказать о циклах. Но пока мы ещё не закончили, давайте рассмотрим оптимизированную версию нашего цикла на do-while и goto</p>\n<p>Т.е если в статье мы рассматривали опкод до оптимизации (Магическое число 0x10000 в <code class=\"language-text\">opcache.opt_debug_level</code> первого примера - это в \"переводе\" \"До оптимизации\") мы видили коды операций в том виде, в каком они были созданы компилятором PHP. Сейчас же мы рассмотрим код после оптимизации (0x20000)</p>\n<p>do-while</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">L0 <span class=\"token punctuation\">(</span>3<span class=\"token punctuation\">)</span>:     ASSIGN CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span> int<span class=\"token punctuation\">(</span>0<span class=\"token punctuation\">)</span>\nL1 <span class=\"token punctuation\">(</span>5<span class=\"token punctuation\">)</span>:     PRE_INC CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span>\nL2 <span class=\"token punctuation\">(</span>6<span class=\"token punctuation\">)</span>:     T1 <span class=\"token operator\">=</span> IS_SMALLER CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span> int<span class=\"token punctuation\">(</span>10<span class=\"token punctuation\">)</span>\nL3 <span class=\"token punctuation\">(</span>6<span class=\"token punctuation\">)</span>:     JMPNZ T1 L1\nL4 <span class=\"token punctuation\">(</span>6<span class=\"token punctuation\">)</span>:     RETURN int<span class=\"token punctuation\">(</span>1<span class=\"token punctuation\">)</span></code></pre></div>\n<p>goto</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">L0 <span class=\"token punctuation\">(</span>3<span class=\"token punctuation\">)</span>:     ASSIGN CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span> int<span class=\"token punctuation\">(</span>0<span class=\"token punctuation\">)</span>\nL1 <span class=\"token punctuation\">(</span>5<span class=\"token punctuation\">)</span>:     PRE_INC CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span>\nL2 <span class=\"token punctuation\">(</span>6<span class=\"token punctuation\">)</span>:     T1 <span class=\"token operator\">=</span> IS_SMALLER CV0<span class=\"token punctuation\">(</span><span class=\"token variable\">$i</span><span class=\"token punctuation\">)</span> int<span class=\"token punctuation\">(</span>10<span class=\"token punctuation\">)</span>\nL3 <span class=\"token punctuation\">(</span>6<span class=\"token punctuation\">)</span>:     JMPNZ T1 L1\nL4 <span class=\"token punctuation\">(</span>8<span class=\"token punctuation\">)</span>:     RETURN int<span class=\"token punctuation\">(</span>1<span class=\"token punctuation\">)</span></code></pre></div>\n<p>Можете не искать отличия, они одинаковы)</p>\n<p>Разница с неоптимизированым кодом, в обоих случаях <code class=\"language-text\">POST_INC</code> заменили на <code class=\"language-text\">PRE_INC</code>,\nчто дало возможность отказаться от выделения памяти под результат и последующего высвобождения её.<br>\nИ в случае с goto инструкции <code class=\"language-text\">JMPZ T3 L6</code> и <code class=\"language-text\">JMP L1</code> превратились в <code class=\"language-text\">JMPNZ T1 L1</code></p>\n<p>На этом всё! Если заметили ошибку или неточности, не стесняйтесь писать мне на почту</p>","excerpt":"В этой статье мы посмотрим, что находится под капотом у PHP циклов, а точнее сравним их опкоды. А вот начнём с самого НЕ часто используемого…"}},"pageContext":{"isCreatedByStatefulCreatePages":false,"type":"posts","next":{"frontmatter":{"path":"/specified-key-was-too-long-max-key-length-is-767-bytes/","title":"Specified key was too long; max key length is 767 bytes","tags":["Laravel"]},"fileAbsolutePath":"/srv/www/softroot.ru/src/posts/2018-02-02-specified-key-was-too-long-max-key-length-is-767-bytes.md"},"previous":{"frontmatter":{"path":"/bolshaia-knigha-pro-vas-i-vashiegho-riebionka/","title":"Большая книга про вас и вашего ребёнка","tags":["Я читаю"]},"fileAbsolutePath":"/srv/www/softroot.ru/src/posts/2018-02-03-bolshaia-knigha-pro-vas-i-vashiegho-riebionka.md"}}}