<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ars Longa, Vita Brevis &#187; оптимизация</title>
	<atom:link href="http://blog.sjinks.pro/tag/optimization/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.sjinks.pro</link>
	<description>Quod scripsi, scripsi</description>
	<lastBuildDate>Mon, 06 Feb 2012 17:56:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Блокировки транзакций InnoDB при удалении данных из таблицы</title>
		<link>http://blog.sjinks.pro/mysql/889-lock-wait-timeout-exceeded-try-restarting-transaction/</link>
		<comments>http://blog.sjinks.pro/mysql/889-lock-wait-timeout-exceeded-try-restarting-transaction/#comments</comments>
		<pubDate>Sat, 05 Feb 2011 16:01:16 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[оптимизация]]></category>
		<category><![CDATA[производительность]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=889</guid>
		<description><![CDATA[Lock wait timeout exceeded; try restarting transaction Ситуация: есть несколько физических почтовых серверов (PowerMTA), отсылающих более четырёх миллионов сообщений в сутки. Есть виртуальный сервер базы данных (причём не очень мощный), на котором крутится MySQL с InnoDB; в базу данных пишутся логи доставки/не доставки сообщений и ведётся статистика по IP-адресам, VMTA и доменам. Попутно выполняется классификация и [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/mysql/889-lock-wait-timeout-exceeded-try-restarting-transaction/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Lock wait timeout exceeded; try restarting transaction</em></h2>
<p>Ситуация: есть несколько физических почтовых серверов (PowerMTA), отсылающих более четырёх миллионов сообщений в сутки. Есть виртуальный сервер базы данных (причём не очень мощный), на котором крутится <a href="http://blog.sjinks.pro/tag/mysql/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  MySQL">MySQL</a> с <a href="http://blog.sjinks.pro/tag/innodb/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  InnoDB">InnoDB</a>; в базу данных пишутся логи доставки/не доставки сообщений и ведётся статистика по IP-адресам, VMTA и доменам. Попутно выполняется классификация и анализ hard и soft bounces. База за день увеличивается примерно на 5 гигабайт. Часть логов недельной давности удаляется.<span id="more-889"></span></p>
<p>Так как с базой (на запись) работает несколько клиентов, структура таблиц/индексы выбраны таким образом, чтобы обеспечить максимальную скорость добавления записей и минимум блокировок.</p>
<p>Проблема возникла с ведением статистики.</p>
<p>Есть таблица такой структуры:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p8894">
        <div class="code mysql" id="p889code4">
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> <span class="kw15">log</span> <span class="br0">&#40;</span><br />
&nbsp; &nbsp; id <span class="kw4">BIGINT</span> <span class="kw6">UNSIGNED</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="kw1">PRIMARY KEY</span> <span class="kw6">AUTO_INCREMENT</span><span class="sy2">,</span><br />
&nbsp; &nbsp; ymd <span class="kw4">INTEGER</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span><span class="sy2">,</span><br />
&nbsp; &nbsp; domain <span class="kw4">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span><span class="sy2">,</span><br />
&nbsp; &nbsp; vmta <span class="kw4">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span><span class="sy2">,</span><br />
&nbsp; &nbsp; ip <span class="kw4">VARCHAR</span><span class="br0">&#40;</span>45<span class="br0">&#41;</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span><span class="sy2">,</span><br />
&nbsp; &nbsp; deliveries <span class="kw4">TINYINT</span> <span class="kw6">UNSIGNED</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span><span class="sy2">,</span><br />
&nbsp; &nbsp; bounces <span class="kw4">TINYINT</span> <span class="kw6">UNSIGNED</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span><span class="sy2">,</span><br />
&nbsp; &nbsp; transients <span class="kw4">TINYINT</span> <span class="kw6">UNSIGNED</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span><span class="sy2">,</span><br />
&nbsp; &nbsp; pmta_bounces <span class="kw4">TINYINT</span> <span class="kw6">UNSIGNED</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span><br />
<span class="br0">&#41;</span> <span class="kw1">ENGINE</span><span class="sy1">=</span><span class="kw1">InnoDB</span> <span class="kw2">DEFAULT</span> <span class="kw7">CHARSET</span><span class="sy1">=</span>utf8<span class="sy2">;</span>
        </div>
    </div>
</div>

<p>В таблицу заносятся данные о доставке сообщений — выполняется это триггерами post insert: при доставке сообщения в таблицу заносится запись <span class="codebox"><code class="mysql"><span class="br0">&#40;</span><span class="kw3">NULL</span><span class="sy2">,</span> <span class="kw17">DATE_FORMAT</span><span class="br0">&#40;</span><span class="kw17">NOW</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy2">,</span> <span class="st0">&quot;<span class="es1">%</span>Y<span class="es1">%</span>m<span class="es1">%</span>d&quot;</span><span class="br0">&#41;</span><span class="sy2">,</span> domain<span class="sy2">,</span> vmta<span class="sy2">,</span> ip<span class="sy2">,</span> <span class="nu0">1</span><span class="sy2">,</span> <span class="nu0">0</span><span class="sy2">,</span> <span class="nu0">0</span><span class="sy2">,</span> <span class="nu0">0</span><span class="sy2">,</span> <span class="nu0">0</span><span class="br0">&#41;</span></code></span>, при получении hard bounce — <span class="codebox"><code class="mysql"><span class="br0">&#40;</span><span class="kw3">NULL</span><span class="sy2">,</span> <span class="kw17">DATE_FORMAT</span><span class="br0">&#40;</span><span class="kw17">NOW</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy2">,</span> <span class="st0">&quot;<span class="es1">%</span>Y<span class="es1">%</span>m<span class="es1">%</span>d&quot;</span><span class="br0">&#41;</span><span class="sy2">,</span> domain<span class="sy2">,</span> vmta<span class="sy2">,</span> ip<span class="sy2">,</span> <span class="nu0">0</span><span class="sy2">,</span> <span class="nu0">1</span><span class="sy2">,</span> <span class="nu0">0</span><span class="sy2">,</span> <span class="nu0">0</span><span class="sy2">,</span> <span class="nu0">0</span><span class="br0">&#41;</span></code></span> — всё это выполняется довольно быстро, жалоб нет.</p>
<p>Проблемы начинаются при обработке данного лога. Что нужно сделать: подсчитать SUM(deliveries), SUM(bounces), SUM(transients), SUM(pmta_bounces) для каждой четвёрки (ymd, domain, vmta, ip). Данная операция выполняется каждые десять минут. Обработанные данные из таблицы log нужно удалить.</p>
<p>В терминах SQL это выглядит примерно так:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p8895">
        <div class="code mysql" id="p889code5">
<span class="kw1">CREATE</span> <span class="kw1">PROCEDURE</span> populate_stats_daily<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="kw1">BEGIN</span><br />
&nbsp; &nbsp; <span class="kw1">DECLARE</span> max_id <span class="kw4">BIGINT</span> <span class="kw6">UNSIGNED</span><span class="sy2">;</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">START</span> <span class="kw1">TRANSACTION</span><span class="sy2">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">SELECT</span> <span class="kw22">MAX</span><span class="br0">&#40;</span>id<span class="br0">&#41;</span> <span class="kw1">INTO</span> max_id <span class="kw1">FROM</span> <span class="kw15">log</span><span class="sy2">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">INSERT</span> <span class="kw1">INTO</span> stats_daily <span class="br0">&#40;</span>ymd<span class="sy2">,</span> domain<span class="sy2">,</span> vmta<span class="sy2">,</span> ip<span class="sy2">,</span> deliveries<span class="sy2">,</span> bounces<span class="sy2">,</span> transients<span class="sy2">,</span> pmta_bounces<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">SELECT</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ymd<span class="sy2">,</span> domain<span class="sy2">,</span> vmta<span class="sy2">,</span> ip<span class="sy2">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw22">SUM</span><span class="br0">&#40;</span>deliveries<span class="br0">&#41;</span> <span class="kw1">AS</span> deliveries<span class="sy2">,</span> <span class="kw22">SUM</span><span class="br0">&#40;</span>bounces<span class="br0">&#41;</span> <span class="kw1">AS</span> bounces<span class="sy2">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw22">SUM</span><span class="br0">&#40;</span>transients<span class="br0">&#41;</span> <span class="kw1">AS</span> transients<span class="sy2">,</span> <span class="kw22">SUM</span><span class="br0">&#40;</span>pmta_bounces<span class="br0">&#41;</span> <span class="kw1">AS</span> pmta_bounces<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">FROM</span> <span class="kw15">log</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">WHERE</span> id <span class="sy1">&lt;=</span> max_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">GROUP BY</span> ymd<span class="sy2">,</span> domain<span class="sy2">,</span> vmta<span class="sy2">,</span> ip<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">ORDER BY</span> <span class="kw3">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">ON</span> <span class="kw1">DUPLICATE KEY</span> <span class="kw1">UPDATE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deliveries &nbsp; <span class="sy1">=</span> deliveries <span class="sy1">+</span> <span class="kw1">VALUES</span><span class="br0">&#40;</span>deliveries<span class="br0">&#41;</span><span class="sy2">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bounces &nbsp; &nbsp; &nbsp;<span class="sy1">=</span> bounces <span class="sy1">+</span> <span class="kw1">VALUES</span><span class="br0">&#40;</span>bounces<span class="br0">&#41;</span><span class="sy2">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transients &nbsp; <span class="sy1">=</span> transients <span class="sy1">+</span> <span class="kw1">VALUES</span><span class="br0">&#40;</span>transients<span class="br0">&#41;</span><span class="sy2">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pmta_bounces <span class="sy1">=</span> pmta_bounces <span class="sy1">+</span> <span class="kw1">VALUES</span><span class="br0">&#40;</span>pmta_bounces<span class="br0">&#41;</span><span class="sy2">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">DELETE</span> <span class="kw1">FROM</span> <span class="kw15">log</span> <span class="kw1">WHERE</span> id <span class="sy1">&lt;=</span> max_id<span class="sy2">;</span><br />
&nbsp; &nbsp; <span class="kw1">COMMIT</span><span class="sy2">;</span><br />
<span class="kw12">END</span>
        </div>
    </div>
</div>

<p>Проблема наступает при выполнении оператора <code>DELETE</code>: <code>SHOW PROCESSLIST</code> показывает состояние <code>Updating</code> минуты полторы, после чего в лог пишется печально известное сообщение <strong>Lock wait timeout exceeded; try restarting transaction</strong> и транзакция откатывается. При этом количество записей в таблице <code>log</code> всего лишь порядка 80,000.</p>
<p>В принципе, проблема с <code>DELETE</code> <a href="http://www.google.ru/search?q=InnoDB+slow+delete">давно известна</a>: в InnoDB удаление строк весьма тормозное. По всей видимости, это усугубляется тем, что в таблицу постоянно идёт запись новых данных. Руководство пользователя <a href="http://dev.mysql.com/doc/refman/5.1/en/innodb-locks-set.html">объясняет</a> суть проблемы.</p>
<p>А решение таково: заводим дополнительную колонку в таблице (<code>processed</code>) и создаём по ней индекс. <code>DELETE FROM log WHERE id <= max_id</code> заменяем на <code>UPDATE log SET processed = 1 WHERE id <= max_id</code>, что выполняется гораздо быстрее. Затем заводим еще одну транзакцию, в которой удаляем строки с <code>processed = 1</code>.</p>
<p>Но в один заход все строки удалить не получится, поэтому придётся идти на хитрость:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p8896">
        <div class="code mysql" id="p889code6">
<span class="kw1">BEGIN</span><br />
&nbsp; &nbsp; <span class="kw1">DECLARE</span> cnt <span class="kw4">BIGINT</span> <span class="kw6">UNSIGNED</span><span class="sy2">;</span><br />
<br />
<span class="coMULTI">/* ... */</span><br />
<br />
&nbsp; &nbsp; <span class="kw13">REPEAT</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">START</span> <span class="kw1">TRANSACTION</span><span class="sy2">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">DELETE</span> <span class="kw1">FROM</span> <span class="kw15">log</span> <span class="kw1">WHERE</span> processed <span class="sy1">=</span> 1 <span class="kw1">LIMIT</span> <span class="nu0">1000</span><span class="sy2">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">SELECT</span> <span class="kw23">ROW_COUNT</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">INTO</span> cnt<span class="sy2">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">COMMIT</span><span class="sy2">;</span><br />
&nbsp; &nbsp; UNTIL cnt <span class="sy1">=</span> 0 <span class="kw12">END</span> <span class="kw13">REPEAT</span><span class="sy2">;</span><br />
<span class="kw12">END</span>
        </div>
    </div>
</div>

<p>Смысл в том, что удаление производится небольшими кусками (что будет относительно быстро); каждое удаление выполняется в своей транзакции (в случае блокировки транзакции в хвосте таблицы большая часть записей будет удалена, что не так плохо).</p>
<p>Вполне возможно, что можно обойтись без дополнительной колонки и использовать <code>REPEAT … END REPEAT</code> с <code>DELETE FROM log WHERE id <= max_id</code>, но текущий вариант работает, кушать не просит, блокировок не создаёт. А наше основное правило — <span title="if it ain't broke, don't fix it">si fractum non sit, noli id reficere</span>.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/mysql/889-lock-wait-timeout-exceeded-try-restarting-transaction/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/mysql/889-lock-wait-timeout-exceeded-try-restarting-transaction/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Небуферизованные запросы: снижаем потребление памяти WordPress</title>
		<link>http://blog.sjinks.pro/wordpress/813-unbuffered-queries-lowering-worpress-memory-requirements/</link>
		<comments>http://blog.sjinks.pro/wordpress/813-unbuffered-queries-lowering-worpress-memory-requirements/#comments</comments>
		<pubDate>Thu, 02 Sep 2010 17:48:38 +0000</pubDate>
		<dc:creator>Wandering Soul</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[база данных]]></category>
		<category><![CDATA[оптимизация]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=813</guid>
		<description><![CDATA[Снижение пикового потребления памяти благодаря в два раза заменой одной функции Пиковое потребление оперативной памяти WordPress можно снизить приблизительно два раза и практически бесплатно. В чём секрет? В использовании правильных функций для работы с базой данных. Опытные программисты знают, что API MySQL предоставляет два варианта работы с результатом запроса: Последовательная обработка результата — при этом не происходит [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/813-unbuffered-queries-lowering-worpress-memory-requirements/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Снижение пикового потребления памяти благодаря в два раза заменой одной функции</em></h2>
<p>Пиковое потребление оперативной памяти <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a> можно снизить приблизительно два раза и практически бесплатно. В чём секрет? В использовании правильных функций для работы с базой данных.</p>
<p>Опытные программисты знают, что API <a href="http://blog.sjinks.pro/tag/mysql/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  MySQL">MySQL</a> предоставляет два варианта работы с результатом запроса:</p>
<ol>
<li>Последовательная обработка результата — при этом не происходит никакой буферизации результата, данные отдаются от сервера клиенту, минуя временные таблицы и буфера. В этом случае обработка результатов может производиться только последовательно.</li>
<li>Буферирование результата запроса — результат полностью читается во временный буфер, что позволяет осуществлять произвольный доступ к результату.</li>
</ol>
<p><span id="more-813"></span></p>
<p>Первому варианту соответствует использование функции <a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a> <a href="http://php.net/manual/en/function.mysql-unbuffered-query.php" rel="nofollow"><code>mysql_unbuffered_query()</code></a>, второму — <a href="http://php.net/manual/en/function.mysql-query.php" rel="nofollow"><code>mysql_query()</code></a>.</p>
<p>WordPress использует именно второй вариант. Но специфика функции <span class="codebox"><code class="php">wpdb<span class="sy0">::</span><span class="me2">query</span><span class="br0">&#40;</span><span class="br0">&#41;</span></code></span> такова, что, выполнив запрос, WordPress полностью читает ответ в переменную <span class="codebox"><code class="php">wpdb<span class="sy0">::</span><span class="me2">last_result</span></code></span>.</p>
<p>Таким образом, при выполнении запроса, возвращающего большой объём данных:</p>
<ol>
<li>MySQL выделит память для временного буфера под <em>весь результат запроса</em></li>
<li>WordPress создаст локальную копию результата запроса</li>
<li>После вызова <code>mysql_result_free()</code> временный буфер будет освобождён</li>
</ol>
<p>В результате связка WordPress + MySQL съест в два раза больше памяти, чем нужно. Это особенно ощутимо на системах с небольшим количеством доступной оперативной памяти.</p>
<p><strong>Лечение:</strong> в файле <code>wp-includes/wp-db.php</code> заменяем <code>mysql_query</code> на <code>mysql_unbuffered_query</code>.</p>
<p><strong>Из бонусов</strong>: при использовании <span class="codebox"><code class="php"><span class="kw3">mysql_unbuffered_query</span><span class="br0">&#40;</span><span class="br0">&#41;</span></code></span> PHP будет получать данные по мере их доступности (во время выполнения запроса), в то время как при использовании <code>mysql_query()</code> пришлось бы ждать окончания выполнения запроса.</p>
<p>Использование небуферизованных запросов, <a href="http://www.moskalyuk.com/blog/mysql_unbuffered_query-faster-than-mysql_query/1318">судя по отзывам</a>, очень сильно позволяет <a href="http://www.tuxradar.com/practicalphp/9/4/9">повысить производительность</a>.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/813-unbuffered-queries-lowering-worpress-memory-requirements/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/813-unbuffered-queries-lowering-worpress-memory-requirements/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>SQLMon для Code Igniter</title>
		<link>http://blog.sjinks.pro/php/769-sqlmon-for-code-igniter/</link>
		<comments>http://blog.sjinks.pro/php/769-sqlmon-for-code-igniter/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 06:10:58 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Code Igniter]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[SQLMon]]></category>
		<category><![CDATA[оптимизация]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=769</guid>
		<description><![CDATA[Мониторинг SQL-запросов в Code Igniter На днях мне довелось заняться оптимизацией одного проекта, написанного с использованием фреймворка Code Igniter. Важной частью процесса являлась оптимизация запросов к базе данных, а для этого как минимум нужно видеть эти запросы перед глазами. Этот минимум в Code Igniter достигается очень просто: вызовом $this-&#62;output-&#62;enable_profiler(TRUE); в контроллере. Но когда запросов на [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/php/769-sqlmon-for-code-igniter/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Мониторинг SQL-запросов в <a href="http://blog.sjinks.pro/tag/code-igniter/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Code Igniter">Code Igniter</a></em></h2>
<p>На днях мне довелось заняться оптимизацией одного проекта, написанного с использованием фреймворка Code Igniter. Важной частью процесса являлась <a href="http://blog.sjinks.pro/tag/optimization/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  оптимизация">оптимизация</a> запросов к базе данных, а для этого как минимум нужно видеть эти запросы перед глазами.</p>
<p>Этот минимум в Code Igniter достигается очень просто: вызовом</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p76910">
        <div class="code php" id="p769code10">
<span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">output</span><span class="sy0">-&gt;</span><span class="me1">enable_profiler</span><span class="br0">&#40;</span><span class="kw4">TRUE</span><span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>в контроллере. Но когда запросов на странице очень много, хотелось бы избавиться от рутинного выполнения <span class="codebox"><code class="mysql"><span class="kw1">EXPLAIN</span></code></span> для каждого подозрительного запроса. Что, собственно, и делает <a href="http://blog.sjinks.pro/tag/sqlmon/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  SQLMon">SQLMon</a>. Возникает логичное желание интегрировать его в Code Igniter.<span id="more-769"></span></p>
<p>Но в отличие от <a href="http://blog.sjinks.pro/kohana/762-sqlmon-for-kohana-3/">Kohana</a>, с Code Igniter здесь не всё так просто. Во-первых, Code Igniter не поддерживает так называемую <dfn><a href="http://v3.kohanaphp.com/guide/about.filesystem">каскадную файловую систему</a></dfn>. Во-вторых, Code Igniter <a href="http://codeigniter.com/user_guide/general/creating_libraries.html">не позволяет</a> расширять или заменять класс <code>Database</code>. А изменять код системы (и поддерживать его при каждом обновлении) очень не хочется. Тем не менее, я нашел простое решение и реализовал соответствующую библиотеку.</p>
<p>Перед использованием библиотеки рекомендуется прочитать статью «<a href="http://dev.mysql.com/doc/refman/5.0/en/using-explain.html">Optimizing Queries with EXPLAIN</a>».</p>
<p><strong>Использование библиотеки.</strong> Библиотека состоит из двух частей:</p>
<ol>
<li><strong>Драйвер базы данных</strong> (каталог <code>system/database/drivers/<a href="http://blog.sjinks.pro/tag/mysql/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  MySQL">mysql</a>_exp</code>). Драйвер требует наличия драйвера MySQL (класс <code>CI_DB_mysql_driver</code>), так как, по сути дела, является производным от него классом. Драйвер переопределяет метод <span class="codebox"><code class="php">_execute<span class="br0">&#40;</span><span class="br0">&#41;</span></code></span>, в котором и выполняет анализ запроса.</li>
<li><strong>Представление (view).</strong> Находится в каталоге <code>system/application/views/sqlmon</code>, используется для отображения результатов.</li>
</ol>
<p>Установка библиотеки простая: содержимое каталога <code>system/database</code> должен быть скопировано в <code>system/database</code>, содержимое каталога <code>system/application</code> должно быть скопировано в каталог приложения. Затем нужно отредактировать настройки соединения с базой данных (файл <code>appliaction/config/database.<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">php</a></code>): параметр <code>dbdriver</code> соединения нужно установить в <code>mysql_exp</code>.</p>
<p>Пример:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p76911">
        <div class="code php" id="p769code11">
<span class="re0">$active_group</span> <span class="sy0">=</span> <span class="st0">&quot;default&quot;</span><span class="sy0">;</span><br />
<span class="re0">$active_record</span> <span class="sy0">=</span> <span class="kw4">TRUE</span><span class="sy0">;</span><br />
<br />
<span class="re0">$db</span><span class="br0">&#91;</span><span class="st_h">'default'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'hostname'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="st0">&quot;localhost&quot;</span><span class="sy0">;</span><br />
<span class="re0">$db</span><span class="br0">&#91;</span><span class="st_h">'default'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'username'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="st0">&quot;username&quot;</span><span class="sy0">;</span><br />
<span class="re0">$db</span><span class="br0">&#91;</span><span class="st_h">'default'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'password'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="st0">&quot;password&quot;</span><span class="sy0">;</span><br />
<span class="re0">$db</span><span class="br0">&#91;</span><span class="st_h">'default'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'database'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="st0">&quot;database&quot;</span><span class="sy0">;</span><br />
<span class="re0">$db</span><span class="br0">&#91;</span><span class="st_h">'default'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'dbdriver'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="st0">&quot;mysql_exp&quot;</span><span class="sy0">;</span> <span class="co1">// &lt;&lt;&lt; Вот оно</span><br />
<span class="re0">$db</span><span class="br0">&#91;</span><span class="st_h">'default'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'dbprefix'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="st0">&quot;mso_&quot;</span><span class="sy0">;</span><br />
<span class="re0">$db</span><span class="br0">&#91;</span><span class="st_h">'default'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'pconnect'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw4">TRUE</span><span class="sy0">;</span><br />
<span class="re0">$db</span><span class="br0">&#91;</span><span class="st_h">'default'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'db_debug'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw4">TRUE</span><span class="sy0">;</span><br />
<span class="re0">$db</span><span class="br0">&#91;</span><span class="st_h">'default'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'cache_on'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw4">FALSE</span><span class="sy0">;</span><br />
<span class="re0">$db</span><span class="br0">&#91;</span><span class="st_h">'default'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'cachedir'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="st0">&quot;system/cache/db&quot;</span><span class="sy0">;</span><br />
<span class="re0">$db</span><span class="br0">&#91;</span><span class="st_h">'default'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'char_set'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="st0">&quot;utf8&quot;</span><span class="sy0">;</span><br />
<span class="re0">$db</span><span class="br0">&#91;</span><span class="st_h">'default'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'dbcollat'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="st0">&quot;utf8_general_ci&quot;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>Затем в соответствующее представление добавляем код:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p76912">
        <div class="code php" id="p769code12">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="re0">$ci</span> <span class="sy0">=</span> <span class="sy0">&amp;</span>get_instance<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="re0">$ci</span><span class="sy0">-&gt;</span><span class="me1">load</span><span class="sy0">-&gt;</span><span class="me1">view</span><span class="br0">&#40;</span><span class="st_h">'sqlmon/sqlmon'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

<p>И наслаждаемся. На выходе должно получиться что-то вида (на примере MaxSite CMS; изображение можно кликнуть):</p>
<p><a href="http://static.sjinks.info/wp-content/uploads/2010/02/codeigniter-sqlmon-maxsite.png" rel="lightbox" title="Результат работы SQLMon для Code Igniter на примере MaxSite CMS"><img src="http://static.sjinks.info/wp-content/uploads/2010/02/codeigniter-sqlmon-maxsite-300x292.png" alt="Результат работы SQLMon для Code Igniter на примере MaxSite CMS" title="Результат работы SQLMon для Code Igniter на примере MaxSite CMS" width="300" height="292" class="alignnone size-medium wp-image-770" /></a></p>
<p><strong><a href="http://d.sjinks.pro/sqlmon-ci.zip">Скачать SQLMon для Code Igniter</a>.</strong></p>
<p></p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/php/769-sqlmon-for-code-igniter/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/php/769-sqlmon-for-code-igniter/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>SQLMon для Kohana 3</title>
		<link>http://blog.sjinks.pro/php/kohana/762-sqlmon-for-kohana-3/</link>
		<comments>http://blog.sjinks.pro/php/kohana/762-sqlmon-for-kohana-3/#comments</comments>
		<pubDate>Tue, 09 Feb 2010 19:16:01 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Kohana]]></category>
		<category><![CDATA[Kohana 3]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[SQLMon]]></category>
		<category><![CDATA[оптимизация]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=762</guid>
		<description><![CDATA[Мониторинг SQL-запросов в Kohana 3 Продолжая славную традицию реализации SQLMon под различные CMS/фреймворки, написал одному заказчику модуль для Kohana 3. SQLMon для Kohana 3 интегрируется в иерархию классов Database (встраивается между классами Database_MySQL и Kohana_Database_MySQL) и реализует обёртку над методом Kohana_Database_MySQL::query(), измеряя время выполнения запроса, объём потребляемой памяти, записывая код ошибки запроса, трассу вызовов и [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/php/kohana/762-sqlmon-for-kohana-3/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Мониторинг SQL-запросов в <a href="http://blog.sjinks.pro/tag/kohana/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Kohana">Kohana</a> 3</em></h2>
<p>Продолжая славную традицию реализации <a href="http://blog.sjinks.pro/tag/sqlmon/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  SQLMon">SQLMon</a> под различные CMS/фреймворки, написал одному заказчику модуль для <a href="http://blog.sjinks.pro/tag/kohana-3/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Kohana 3">Kohana 3</a>.</p>
<p>SQLMon для Kohana 3 интегрируется в иерархию классов Database (встраивается между классами <code>Database_<a href="http://blog.sjinks.pro/tag/mysql/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  MySQL">MySQL</a></code> и <code>Kohana_Database_MySQL</code>) и реализует обёртку над методом <span class="codebox"><code class="php">Kohana_Database_MySQL<span class="sy0">::</span><span class="me2">query</span><span class="br0">&#40;</span><span class="br0">&#41;</span></code></span>, измеряя время выполнения запроса, объём потребляемой памяти, записывая код ошибки запроса, трассу вызовов и <span class="codebox"><code class="mysql"><span class="kw1">EXPLAIN</span></code></span> запроса (причём не только для <span class="codebox"><code class="mysql"><span class="kw1">SELECT</span></code></span>, но и <span class="codebox"><code class="mysql"><span class="kw1">UPDATE</span></code></span>/<span class="codebox"><code class="mysql"><span class="kw1">DELETE</span></code></span> и <span class="codebox"><code class="mysql"><span class="kw2">INSERT</span></code></span>/<span class="codebox"><code class="mysql"><span class="kw2">REPLACE</span> <span class="kw1">INTO</span> … <span class="kw1">AS</span></code></span> или <span class="codebox"><code class="mysql"><span class="kw1">CREATE</span> &nbsp;<span class="kw1">TABLE</span> … <span class="kw1">AS</span></code></span>) — всё то же самое, что и <a href="http://blog.sjinks.pro/wordpress-plugins/sqlmon/">SQLMon для WordPress</a>.<span id="more-762"></span></p>
<p>Данный модуль будет полезен разработчикам для анализа производительности запросов MySQL и поиска решений для их оптимизации. Перед использованием модуля рекомендуется прочитать статью «<a href="http://dev.mysql.com/doc/refman/5.0/en/using-explain.html">Optimizing Queries with EXPLAIN</a>».</p>
<p><strong>Использование модуля.</strong> Модуль должен быть распакован в каталог <code>modules</code> проекта (после распаковки появится каталог <code>sqlmon</code>). Затем модуль должен быть активирован в файле <code>application/bootstrap.<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">php</a></code>. Очень важно, чтобы модуль подключался <strong>перед модулем <code>database</code></strong> — это связано с <a href="http://v3.kohanaphp.com/guide/about.filesystem">особенностями поиска классов в Kohana 3</a>.</p>
<p>Например:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p76216">
        <div class="code php" id="p762code16">
Kohana<span class="sy0">::</span><span class="me2">modules</span><span class="br0">&#40;</span><span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st_h">'sqlmon'</span> &nbsp; &nbsp; <span class="sy0">=&gt;</span> MODPATH<span class="sy0">.</span><span class="st_h">'sqlmon'</span><span class="sy0">,</span> &nbsp; &nbsp; <span class="co1">// SQL Monitor — обязательно перед Database</span><br />
&nbsp; &nbsp; <span class="st_h">'database'</span> &nbsp; <span class="sy0">=&gt;</span> MODPATH<span class="sy0">.</span><span class="st_h">'database'</span><span class="sy0">,</span> &nbsp; <span class="co1">// Database access</span><br />
&nbsp; &nbsp; <span class="st_h">'orm'</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> MODPATH<span class="sy0">.</span><span class="st_h">'orm'</span><span class="sy0">,</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">// Object Relationship Mapping</span><br />
&nbsp; &nbsp; <span class="st_h">'pagination'</span> <span class="sy0">=&gt;</span> MODPATH<span class="sy0">.</span><span class="st_h">'pagination'</span><span class="sy0">,</span> <span class="co1">// Paging of results</span><br />
<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>Для отображения статистики нужно выполнить</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p76217">
        <div class="code php" id="p762code17">
<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> View<span class="sy0">::</span><span class="me2">factory</span><span class="br0">&#40;</span><span class="st_h">'sqlmon/sqlmon'</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

<p>Результатом будет нечто вида (скриншот можно кликнуть):</p>
<p><a href="http://static.sjinks.info/wp-content/uploads/2010/02/kohana-sqlmon.png" rel="lightbox" title="SQLMon для Kohana — пример работы"><img src="http://static.sjinks.info/wp-content/uploads/2010/02/kohana-sqlmon-300x136.png" alt="SQLMon для Kohana — пример работы" title="SQLMon для Kohana — пример работы" width="300" height="136" class="size-medium wp-image-763" /></a></p>
<p><strong>Настройка.</strong> SQLMon использует файлы конфигурации модуля Database — <code>config/database.php</code>. Для контроля поведения SQLMon нужно использовать параметры:</p>
<ul>
<li><code>backtrace</code> — <code>boolean</code> (по умолчанию true) — должен ли SQLMon отображать трассу вызовов (то, что отображается синим цветом на скриншоте выше);</li>
<li><code>explain</code> — <code>boolean</code> (по умолчанию true) — должен ли SQLMon отображать план выполнения запросов (<span class="codebox"><code class="mysql"><span class="kw1">EXPLAIN</span></code></span>).</li>
</ul>
<p>Пример файла конфигурации:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p76218">
        <div class="code php" id="p762code18">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'default'</span> <span class="sy0">=&gt;</span> <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'type'</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'mysql'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'profiling'</span> &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'charset'</span> &nbsp; &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="st_h">'utf8'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'table_prefix'</span> &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Настройки SQLMon</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'backtrace'</span> &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'explain'</span> &nbsp; &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// ---</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'connection'</span> &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'username'</span> &nbsp; <span class="sy0">=&gt;</span> <span class="st_h">'root'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'password'</span> &nbsp; <span class="sy0">=&gt;</span> <span class="st_h">'M1dn19ht'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'hostname'</span> &nbsp; <span class="sy0">=&gt;</span> <span class="st_h">'localhost'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'persistent'</span> <span class="sy0">=&gt;</span> <span class="kw4">false</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'database'</span> &nbsp; <span class="sy0">=&gt;</span> <span class="st_h">'feedfetcher'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

<p><strong><a href="http://d.sjinks.pro/kohana/sqlmon.zip">Скачать SQLMon для Kohana 3</a>.</strong></p>
<p></p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/php/kohana/762-sqlmon-for-kohana-3/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/php/kohana/762-sqlmon-for-kohana-3/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Оптимизация изображений без потерь</title>
		<link>http://blog.sjinks.pro/linux/710-lossless-image-optimization/</link>
		<comments>http://blog.sjinks.pro/linux/710-lossless-image-optimization/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 19:18:49 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[оптимизация]]></category>
		<category><![CDATA[сжатие]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=710</guid>
		<description><![CDATA[Smush.IT™ на локальном компьютере Внимание: в данной статье описывается скрипт оптимизации изображений для Linux. Если вы ищите программу для оптимизации изображений для Windows, то это PictureBeaver. Один из советов по ускорению загрузки сайта, который даёт Yahoo! Exceptional Performance Team — это оптимизация изображений. Оптимизация без потерь (рассматриваться будет именно она) позволяет уменьшить размер изображений (временами очень [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/linux/710-lossless-image-optimization/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Smush.IT™ на локальном компьютере</em></h2>
<p><strong>Внимание:</strong> в данной статье описывается скрипт оптимизации изображений <strong>для <a href="http://blog.sjinks.pro/tag/linux/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Linux">Linux</a></strong>. Если вы ищите программу для оптимизации изображений <strong>для Windows</strong>, то это <a href="http://sapegin.ru/picturebeaver">PictureBeaver</a>.</p>
<p>Один из советов по ускорению загрузки сайта, который даёт Yahoo! Exceptional Performance Team — это <a href="http://developer.yahoo.com/performance/rules.html#opt_images">оптимизация изображений</a>. <a href="http://blog.sjinks.pro/tag/optimization/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  оптимизация">Оптимизация</a> без потерь (рассматриваться будет именно она) позволяет уменьшить размер изображений (временами очень даже значительно) и за счёт этого уменьшить общее время, требуемое для загрузки страницы.</p>
<p>Уменьшение размера изображения без потери качества достигается рядом способов:</p>
<ul>
<li>использование другого алгоритма сжатия данных либо использование более агрессивных параметров (как правило, чем выше степень сжатия, тем больше времени уходит на <a href="http://blog.sjinks.pro/tag/compression/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  сжатие">сжатие</a>);</li>
<li>удаление информационных блоков, наличие или отсутствие которых не влияет на декодирование изображения;</li>
<li>оптимизация цветов (например, если изображение сохранено в формате PNG32 — 4 <strong>байта</strong> на пиксель, но реально используются только 16 цветов — 4 <strong>бита</strong> на пиксель, то оптимизация цветов (color reduction) позволит значительно уменьшить размер файла).</li>
</ul>
<p>Yahoo! предоставляет бесплатный сервис <a href="http://developer.yahoo.com/yslow/smushit/">Yahoo! Smush.it™</a>, который позволяет оптимизировать графику в онлайн-режиме, но его использование не всегда удобно. Гораздо удобнее, когда всё можно сделать на своём компьютере.<span id="more-710"></span></p>
<p>Нам понадобятся:</p>
<ul>
<li><a href="http://www.lcdf.org/gifsicle/">gifsicle</a> для оптимизации GIF-изображений и анимаций;</li>
<li><a href="http://optipng.sourceforge.net/">optipng</a> для оптимального сжатия PNG-файлов (что достигается путём перебора множества параметров, влияющих на работу алгоритма сжатия);</li>
<li><a href="http://pmt.sourceforge.net/pngcrush/">pngcrush</a> для удаления лишних блоков из PNG-файла. Как и optipng, pngcrush умеет определять оптимальные параметры сжатия (optipng — это форк pngcrush), но, как показали тесты, у optipng это получается чуть лучше;</li>
<li><a href="http://sylvana.net/jpegcrop/jpegtran/">jpegtran</a> позволяет выполнять преобразования без потерь над файлами JPEG (в частности, удаление лишних информационных блоков и перестраивание данных — коэффициентов дискретно-косинусного преобразования);</li>
<li><a href="http://www.imagemagick.org/script/index.php">ImageMagick</a> для определения формата изображений;</li>
<li><a href="http://advancemame.sourceforge.net/comp-readme.html">AdvanceCOMP</a> позволяет достичь лучших результатов сжатия PNG-файлов, благодаря использованию реализации 7-Zip Defalte.</li>
</ul>
<p>Весь этот зоопарк в дистрибутивах Linux, основанных на Debian, устанавливается так:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p71022">
        <div class="code bash" id="p710code22">
<span class="kw2">sudo</span> <span class="kw2">apt-get</span> <span class="kw2">install</span> advancecomp gifsicle optipng libjpeg-progs imagemagick pngcrush
        </div>
    </div>
</div>

<p>Затем загружаем этот скрипт:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p71023">
        <div class="code bash" id="p710code23">
<span class="co0">#! /bin/sh</span><br />
<br />
<span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re5">-z</span> <span class="st0">&quot;$1&quot;</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Usage: optimize-image.sh filename&quot;</span><br />
&nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">1</span>;<br />
<span class="kw1">fi</span><br />
<br />
<span class="kw1">if</span> <span class="br0">&#91;</span> <span class="sy0">!</span> <span class="re5">-f</span> <span class="st0">&quot;$1&quot;</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;$1 is not a file&quot;</span><br />
&nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">1</span>;<br />
<span class="kw1">fi</span><br />
<br />
<span class="re2">TYPE</span>=<span class="sy0">`</span>identify <span class="st0">&quot;$1&quot;</span> <span class="sy0">|</span> <span class="kw2">grep</span> <span class="re5">-E</span> <span class="re5">-o</span> <span class="st_h">'JPEG|GIF|PNG'</span><span class="sy0">`</span><br />
<span class="re2">OLD</span>=<span class="sy0">`</span><span class="kw2">stat</span> <span class="re5">-c</span> <span class="sy0">%</span>s <span class="st0">&quot;$1&quot;</span><span class="sy0">`</span><br />
<br />
<span class="kw1">case</span> <span class="st0">&quot;<span class="es2">$TYPE</span>&quot;</span> <span class="kw1">in</span><br />
&nbsp; &nbsp; JPEG<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; jpegtran <span class="re5">-copy</span> none <span class="re5">-optimize</span> <span class="re5">-perfect</span> <span class="re5">-progressive</span> <span class="re5">-outfile</span> <span class="st0">&quot;$1.tmp&quot;</span> <span class="st0">&quot;$1&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; jpegtran <span class="re5">-copy</span> none <span class="re5">-optimize</span> <span class="re5">-perfect</span> <span class="re5">-outfile</span> <span class="st0">&quot;$1.tmq&quot;</span> <span class="st0">&quot;$1&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re5">-f</span> <span class="st0">&quot;$1.tmp&quot;</span> <span class="re5">-a</span> <span class="re5">-f</span> <span class="st0">&quot;$1.tmq&quot;</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">S_PROG</span>=<span class="sy0">`</span><span class="kw2">stat</span> <span class="re5">-c</span> <span class="sy0">%</span>s <span class="st0">&quot;$1.tmp&quot;</span><span class="sy0">`</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">S_NORM</span>=<span class="sy0">`</span><span class="kw2">stat</span> <span class="re5">-c</span> <span class="sy0">%</span>s <span class="st0">&quot;$1.tmq&quot;</span><span class="sy0">`</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re1">$S_PROG</span> <span class="re5">-ge</span> <span class="re1">$S_NORM</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">mv</span> <span class="re5">-f</span> <span class="st0">&quot;$1.tmq&quot;</span> <span class="st0">&quot;$1&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">rm</span> <span class="re5">-f</span> <span class="st0">&quot;$1.tmp&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">mv</span> <span class="re5">-f</span> <span class="st0">&quot;$1.tmp&quot;</span> <span class="st0">&quot;$1&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">rm</span> <span class="re5">-f</span> <span class="st0">&quot;$1.tmq&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fi</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fi</span><br />
&nbsp; &nbsp; <span class="sy0">;;</span><br />
<br />
&nbsp; &nbsp; GIF<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; gifsicle <span class="re5">-O2</span> <span class="re5">-b</span> <span class="st0">&quot;$1&quot;</span><br />
&nbsp; &nbsp; <span class="sy0">;;</span><br />
<br />
&nbsp; &nbsp; PNG<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; pngcrush <span class="re5">-q</span> <span class="re5">-rem</span> alla <span class="re5">-fix</span> <span class="st0">&quot;$1&quot;</span> <span class="st0">&quot;$1.tmp&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re5">-f</span> <span class="st0">&quot;$1.tmp&quot;</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">mv</span> <span class="re5">-f</span> <span class="st0">&quot;$1.tmp&quot;</span> <span class="st0">&quot;$1&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fi</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; optipng <span class="re5">-zc6-9</span> <span class="re5">-zm1-9</span> <span class="re5">-zs0-3</span> <span class="re5">-f0-5</span> <span class="re5">-q</span> <span class="re5">-fix</span> <span class="st0">&quot;$1&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; advpng <span class="re5">-z</span> <span class="re5">-4</span> <span class="re5">-q</span> <span class="st0">&quot;$1&quot;</span><br />
&nbsp; &nbsp; <span class="sy0">;;</span><br />
<span class="kw1">esac</span><br />
<br />
<span class="re2">NEW</span>=<span class="sy0">`</span><span class="kw2">stat</span> <span class="re5">-c</span> <span class="sy0">%</span>s <span class="st0">&quot;$1&quot;</span><span class="sy0">`</span><br />
<span class="kw3">echo</span> <span class="st0">&quot;$1, old size: <span class="es2">$OLD</span>, new size: <span class="es2">$NEW</span>&quot;</span>
        </div>
    </div>
</div>

<p>Файл должен быть исполняемым,так что не забываем ставить соответствующие права.</p>
<p>Для JPEG-файлов пробуется два разных способа кодирования: Progressive (низкочастотные коэффициенты находятся в начале файла) и обычное кодирование. В зависимости от изображение, Progressive JPEG может быть меньшим по размеру, чем non-progressive JPEG и наоборот.</p>
<p>Из PNG-файлов удаляются все лишние информационные блоки, после чего выполняется поиск оптимального варианта сжатия. Файл, сжатый optipng, обрабатывается advpng, который, в ряде случаев, позволяет достичь еще большего коэффициента сжатия.</p>
<p>GIF-файлы обрабатываются только gifsicle, я не добавлял код, который бы преобразовывал GIF в PNG и проверял, что лучше (так как в этом случае пришлось бы руками исправлять все ссылки на GIF-файл и заменять их ссылками на PNG).</p>
<p>Пример использования:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p71024">
        <div class="code bash" id="p710code24">
<span class="kw2">find</span> <span class="re5">-type</span> f \<span class="br0">&#40;</span> <span class="re5">-name</span> <span class="st0">&quot;*.png&quot;</span> <span class="re5">-o</span> <span class="re5">-name</span> <span class="st0">&quot;*.gif&quot;</span> <span class="re5">-o</span> <span class="re5">-name</span> <span class="st0">&quot;*.jpg&quot;</span> <span class="re5">-o</span> <span class="re5">-name</span> <span class="st0">&quot;*.JPG&quot;</span> \<span class="br0">&#41;</span> <span class="re5">-exec</span> optimize-image.sh <span class="st_h">'{}'</span> \;
        </div>
    </div>
</div>

<p><strong style="color: red">Внимание, перед использованием скрипта не забываем о необходимости резервного копирования!</strong> Хотя скрипт и тестировался в боевых условиях, осторожность никто не отменял.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/linux/710-lossless-image-optimization/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/linux/710-lossless-image-optimization/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Еще одна оптимизация NextGen Gallery</title>
		<link>http://blog.sjinks.pro/wordpress/patches/703-yet-another-nextgen-gallery-optimization/</link>
		<comments>http://blog.sjinks.pro/wordpress/patches/703-yet-another-nextgen-gallery-optimization/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 21:19:54 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Патчи]]></category>
		<category><![CDATA[NextGen Gallery]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[оптимизация]]></category>
		<category><![CDATA[патч]]></category>
		<category><![CDATA[плагин]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=703</guid>
		<description><![CDATA[Минус один UPDATE при каждом обращении к блогу Плагин NextGen Gallery имеет одну неприятную особенность: при каждом обращении к блогу выполняется обновление (UPDATE в терминах MySQL) таблицы wp_options. Хотя для «средних» блогов это не критично, для хорошо посещаемых ресурсов это плохо по ряду причин: Обновление таблицы wp_options сбрасывает кэш запросов MySQL к таблице wp_options, что [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/patches/703-yet-another-nextgen-gallery-optimization/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Минус один UPDATE при каждом обращении к блогу</em></h2>
<p><a href="http://blog.sjinks.pro/tag/plugin/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  плагин">Плагин</a> <a href="http://blog.sjinks.pro/tag/nextgen-gallery/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  NextGen Gallery">NextGen Gallery</a> имеет одну неприятную особенность: при каждом обращении к блогу выполняется обновление (<span class="codebox"><code class="mysql"><span class="kw1">UPDATE</span></code></span> в терминах <a href="http://blog.sjinks.pro/tag/mysql/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  MySQL">MySQL</a>) таблицы <code>wp_options</code>. Хотя для «средних» блогов это не критично, для хорошо посещаемых ресурсов это плохо по ряду причин:</p>
<ol>
<li>Обновление таблицы <code>wp_options</code> сбрасывает кэш запросов MySQL к таблице <code>wp_options</code>, что приводит к необходимости реального выполнения запросов на выборку данных (с учётом огромного количества записей — благодаря всяким разным плагинам — это лишний трафик между <a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a> и MySQL).</li>
<li>Выполнение операции обновления таблицы при использовании MyISAM приводит к блокировке таблицы; при высокой посещаемости это приводит к вынужденному ожиданию освобождения таблицы и негативно сказывается на нагрузке и производительности.</li>
<li>При использовании плагинов объектного кэширования каждый вызов <span class="codebox"><code class="php">update_option<span class="br0">&#40;</span><span class="br0">&#41;</span></code></span> приводит к необходимости обновления и записи кэша; обновление файлового объектного кэша приводит к лишним обращениям к диску (которых на виртуальных серверах лучше избегать).</li>
<li>В конце концов, это лишний запрос, который <strong>не является необходимым</strong>.</li>
</ol>
<p><span id="more-703"></span></p>
<p>Использование плагина <a href="http://blog.sjinks.pro/wordpress-plugins/sqlmon/">MySQL Monitor</a> показывает:</p>
<ul>
<li><strong>Запрос:</strong>
          
<div class="codebox">
    <div class="the_code" style="" id="p70328">
        <div class="code mysql" id="p703code28">
<span class="kw1">UPDATE</span> <span class="st0">`wp<span class="es1">_</span>options`</span> <span class="kw1">SET</span> <span class="st0">`option<span class="es1">_</span>value`</span> <span class="sy1">=</span> <span class="st0">'a:3:{i:0;b:0;s:29:<span class="es0">\&quot;</span>nextgen-gallery/nggallery.php<span class="es0">\&quot;</span>;a:2:{i:0;s:9:<span class="es0">\&quot;</span>nggLoader<span class="es0">\&quot;</span>;i:1;s:9:<span class="es0">\&quot;</span>uninstall<span class="es0">\&quot;</span>;}...}'</span> <span class="kw1">WHERE</span> <span class="st0">`option<span class="es1">_</span>name`</span> <span class="sy1">=</span> <span class="st0">'uninstall<span class="es1">_</span>plugins'</span>
        </div>
    </div>
</div>

</li>
<li><strong>Трасса вызовов:</strong>
          
<div class="codebox">
    <div class="the_code" style="" id="p70329">
        <div class="code text" id="p703code29">
wp-includes/wp-db.php, 830 (DbProfile::query)<br />
wp-includes/functions.php, 533 (wpdb::update)<br />
wp-includes/plugin.php, 608 (update_option)<br />
wp-content/plugins/nextgen-gallery/nggallery.php, 80 (register_uninstall_hook)<br />
wp-content/plugins/nextgen-gallery/nggallery.php, 429 (nggLoader::nggLoader)<br />
wp-settings.php, 566 (include_once)<br />
wp-config.php, 84 (require_once)<br />
wp-load.php, 30 (require_once)<br />
wp-blog-header.php, 12 (require_once)<br />
index.php, 17 (require)
        </div>
    </div>
</div>

</li>
</ul>
<p>Говоря простым языком, NextGen Gallery <strong>при каждой загрузке <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a></strong> регистрирует функцию деинсталляции плагина. Таким образом, если мы имеем 25,000 показов страниц в день, это выливается в 25,000 (относительно медленных) запросов <code>UPDATE</code> к базе.</p>
<p>Проблема решается очень просто: вызов функции <span class="codebox"><code class="php">register_uninstall_hook</code></span> переносится из конструктора <span class="codebox"><code class="php">nggLoader<span class="sy0">::</span><span class="me2">nggLoader</span><span class="br0">&#40;</span><span class="br0">&#41;</span></code></span> (файл <code>nextgen-gallery/nggallery.php</code>) в самый конец функции <span class="codebox"><code class="php">nggLoader<span class="sy0">::</span><span class="me2">activate</span><span class="br0">&#40;</span><span class="br0">&#41;</span></code></span> (за строку <span class="codebox"><code class="php">delete_option<span class="br0">&#40;</span> <span class="st_h">'ngg_update_exists'</span> <span class="br0">&#41;</span><span class="sy0">;</span></code></span>).</p>
<p>Получаем простой <a href="http://blog.sjinks.pro/tag/patch/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  патч">патч</a>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p70330">
        <div class="code diff" id="p703code30">
--- nggallery.php.old &nbsp; 2009-11-23 22:06:09.000000000 +0200<br />
<span class="re4">+++ nggallery.php &nbsp; &nbsp; &nbsp; <span class="nu0">2009</span>-<span class="nu0">11</span>-<span class="nu0">23</span> <span class="nu0">22</span>:07:<span class="nu0">55.000000000</span> +0200</span><br />
<span class="re6">@@ -<span class="nu0">76</span>,<span class="nu0">9</span> +<span class="nu0">76</span>,<span class="nu0">6</span> @@</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; register_activation_hook<span class="br0">&#40;</span> $this-&gt;plugin_name, array<span class="br0">&#40;</span>&amp;$this, 'activate'<span class="br0">&#41;</span> <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; register_deactivation_hook<span class="br0">&#40;</span> $this-&gt;plugin_name, array<span class="br0">&#40;</span>&amp;$this, 'deactivate'<span class="br0">&#41;</span> <span class="br0">&#41;</span>;&nbsp; <br />
&nbsp;<br />
<span class="re7">- &nbsp; &nbsp; &nbsp; // Register a uninstall hook to remove all tables &amp; option automatic</span><br />
<span class="re7">- &nbsp; &nbsp; &nbsp; register_uninstall_hook<span class="br0">&#40;</span> $this-&gt;plugin_name, array<span class="br0">&#40;</span>'nggLoader', 'uninstall'<span class="br0">&#41;</span> <span class="br0">&#41;</span>;</span><br />
<span class="re7">-</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; // Start this plugin once all other plugins are fully loaded<br />
&nbsp; &nbsp; &nbsp; &nbsp; add_action<span class="br0">&#40;</span> 'plugins_loaded', array<span class="br0">&#40;</span>&amp;$this, 'start_plugin'<span class="br0">&#41;</span> <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
<span class="re6">@@ -<span class="nu0">376</span>,<span class="nu0">6</span> +<span class="nu0">373</span>,<span class="nu0">8</span> @@</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; // remove the update message<br />
&nbsp; &nbsp; &nbsp; &nbsp; delete_option<span class="br0">&#40;</span> 'ngg_update_exists' <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
<span class="re8">+ &nbsp; &nbsp; &nbsp; // Register a uninstall hook to remove all tables &amp; option automatic</span><br />
<span class="re8">+ &nbsp; &nbsp; &nbsp; register_uninstall_hook<span class="br0">&#40;</span> $this-&gt;plugin_name, array<span class="br0">&#40;</span>'nggLoader', 'uninstall'<span class="br0">&#41;</span> <span class="br0">&#41;</span>;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; function deactivate<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        </div>
    </div>
</div>

<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/patches/703-yet-another-nextgen-gallery-optimization/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/patches/703-yet-another-nextgen-gallery-optimization/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>PHP: красота кода сказывается на производительности: часть 2</title>
		<link>http://blog.sjinks.pro/php/651-php-code-beauty-impacts-performance-part-2/</link>
		<comments>http://blog.sjinks.pro/php/651-php-code-beauty-impacts-performance-part-2/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 01:23:25 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[оптимизация]]></category>
		<category><![CDATA[производительность]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=651</guid>
		<description><![CDATA[Как же всё запущено В прошлой части: if быстрее, чем switch; echo быстрее, чем print; явная проверка на (не)нулевое значение медленнее, чем неявная. А также: константные выражения, которые могут быть вычислены на этапе компиляции, не вычисляются; PHP не умеет удалять неиспользуемый код на этапе компиляции. Продолжим. Конкатенация или переменные внутри строки? &#160; Конкатенация Переменные внутри [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/php/651-php-code-beauty-impacts-performance-part-2/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Как же всё запущено</em></h2>
<p>В <a href="http://blog.sjinks.pro/php/650-php-code-beauty-impacts-performance/">прошлой части</a>:</p>
<ul>
<li><span class="codebox"><code class="php"><span class="kw1">if</span></code></span> быстрее, чем <span class="codebox"><code class="php"><span class="kw1">switch</span></code></span>;</li>
<li><span class="codebox"><code class="php"><span class="kw1">echo</span></code></span> быстрее, чем <span class="codebox"><code class="php"><span class="kw1">print</span></code></span>;</li>
<li>явная проверка на (не)нулевое значение медленнее, чем неявная.</li>
</ul>
<p><a href="http://blog.sjinks.pro/php/638-byte-code-optimization-in-php/">А также</a>: </p>
<ul>
<li>константные выражения, которые могут быть вычислены на этапе компиляции, не вычисляются;</li>
<li><a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a> не умеет удалять неиспользуемый код на этапе компиляции.</li>
</ul>
<p>Продолжим.<span id="more-651"></span></p>
<h3>Конкатенация или переменные внутри строки?</h3>
<table class="bordered" style="width: 99%; table-layout:fixed">
<thead>
<tr>
<th style="width: 100px">&nbsp;</th>
<th style="width: 50%">Конкатенация</th>
<th style="width: 50%">Переменные внутри строки</th>
</tr>
</thead>
<tbody style="vertical-align: top">
<tr>
<th scope="row">Код</th>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65153">
        <div class="code php" id="p651code53">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="re0">$tpl</span> &nbsp;<span class="sy0">=</span> <span class="st0">&quot;str2&quot;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="re0">$text</span> <span class="sy0">=</span> <span class="st_h">'str1 '</span> <span class="sy0">.</span> <span class="re0">$tpl</span> <span class="sy0">.</span> <span class="st0">&quot; str3<span class="es1">\n</span>&quot;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">echo</span> <span class="re0">$text</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

</td>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65154">
        <div class="code php" id="p651code54">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="re0">$tpl</span> &nbsp;<span class="sy0">=</span> <span class="st0">&quot;str2&quot;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="re0">$text</span> <span class="sy0">=</span> <span class="st0">&quot;str1 <span class="es4">{$tpl}</span> str3<span class="es1">\n</span>&quot;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">echo</span> <span class="re0">$text</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

</td>
</tr>
<tr>
<th>Результат</th>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65155">
        <div class="code text" id="p651code55">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $tpl, 'str2'<br />
&nbsp; &nbsp;3 &nbsp; &nbsp; 1 &nbsp;CONCAT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1 &nbsp; &nbsp; &nbsp;'str1 ', $tpl<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp;CONCAT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~2 &nbsp; &nbsp; &nbsp;~1, ' str3\n'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $text, ~2<br />
&nbsp; &nbsp;4 &nbsp; &nbsp; 4 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $text<br />
&nbsp; &nbsp;6 &nbsp; &nbsp; 5 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

</td>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65156">
        <div class="code text" id="p651code56">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $tpl, 'str2'<br />
&nbsp; &nbsp;3 &nbsp; &nbsp; 1 &nbsp;INIT_STRING &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;~1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp;ADD_STRING &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1 &nbsp; &nbsp; &nbsp;~1, 'str1 '<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp;ADD_VAR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;~1 &nbsp; &nbsp; &nbsp;~1, $tpl<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4 &nbsp;ADD_STRING &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1 &nbsp; &nbsp; &nbsp;~1, ' str3\n'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;5 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $text, ~1<br />
&nbsp; &nbsp;4 &nbsp; &nbsp; 6 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $text<br />
&nbsp; &nbsp;6 &nbsp; &nbsp; 7 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;8* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

</td>
</tr>
</tbody>
</table>
<p><strong>Вывод:</strong> конкатенация быстрее, и, как показал тест (путём замены <span class="codebox"><code class="php"><span class="kw1">echo</span> <span class="re0">$text</span><span class="sy0">;</span></code></span> на <span class="codebox"><code class="php"><span class="kw1">echo</span> <span class="kw3">memory_get_usage</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></code></span>), потребляет меньше памяти.</p>
<h3>Цикл со счётчиком: <span class="codebox"><code class="php"><span class="kw1">while</span></code></span> или <span class="codebox"><code class="php"><span class="kw1">for</span></code></span>?</h3>
<table class="bordered" style="width: 99%; table-layout:fixed">
<thead>
<tr>
<th style="width: 100px">&nbsp;</th>
<th style="width: 50%"><span class="codebox"><code class="php"><span class="kw1">for</span></code></span></th>
<th style="width: 50%"><span class="codebox"><code class="php"><span class="kw1">while</span></code></span></th>
</tr>
</thead>
<tbody style="vertical-align: top">
<tr>
<th scope="row">Код</th>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65157">
        <div class="code php" id="p651code57">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="re0">$i</span><span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">&lt;</span><span class="nu0">1000</span><span class="sy0">;</span> <span class="sy0">++</span><span class="re0">$i</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

</td>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65158">
        <div class="code php" id="p651code58">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="re0">$i</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span><span class="re0">$i</span><span class="sy0">&lt;</span>1000<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">++</span><span class="re0">$i</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

</td>
</tr>
<tr>
<th>Результат</th>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65159">
        <div class="code text" id="p651code59">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $i, 0<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp;IS_SMALLER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1 &nbsp; &nbsp; &nbsp;$i, 1000<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp;JMPZNZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;~1, -&gt;6<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp;PRE_INC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$i<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4 &nbsp;JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;1<br />
&nbsp; &nbsp;3 &nbsp; &nbsp; 5 &nbsp;JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;3<br />
&nbsp; &nbsp;7 &nbsp; &nbsp; 6 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;7* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

</td>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65160">
        <div class="code text" id="p651code60">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $i, 0<br />
&nbsp; &nbsp;3 &nbsp; &nbsp; 1 &nbsp;IS_SMALLER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1 &nbsp; &nbsp; &nbsp;$i, 1000<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1, -&gt;5<br />
&nbsp; &nbsp;4 &nbsp; &nbsp; 3 &nbsp;PRE_INC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;!0<br />
&nbsp; &nbsp;5 &nbsp; &nbsp; 4 &nbsp;JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;1<br />
&nbsp; &nbsp;9 &nbsp; &nbsp; 5 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

</td>
</tr>
</tbody>
</table>
<p><strong>Вывод:</strong> хотя цикл <span class="codebox"><code class="php"><span class="kw1">while</span></code></span> выглядит многословнее (по крайней мере, длиннее), он, на удивление, оказывается короче полностью аналогичного цикла <span class="codebox"><code class="php"><span class="kw1">for</span></code></span>. Таким образом, не всегда более короткий код оказывается более эффективным. При этом так как второй вариант короче (в плане количества опкодов), он потребляет меньше памяти.</p>
<h3>Пустая строка или <span class="codebox"><code class="php"><span class="kw4">NULL</span></code></span>?</h3>
<table class="bordered" style="width: 99%; table-layout:fixed">
<thead>
<tr>
<th style="width: 100px">&nbsp;</th>
<th style="width: 50%">Пустая строка</th>
<th style="width: 50%"><span class="codebox"><code class="php"><span class="kw4">null</span></code></span></th>
</tr>
</thead>
<tbody style="vertical-align: top">
<tr>
<th scope="row">Код</th>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65161">
        <div class="code php" id="p651code61">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="re0">$a</span> <span class="sy0">=</span> <span class="st0">&quot;&quot;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">echo</span> <span class="kw3">memory_get_usage</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

</td>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65162">
        <div class="code php" id="p651code62">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="re0">$a</span> <span class="sy0">=</span> <span class="kw4">NULL</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">echo</span> <span class="kw3">memory_get_usage</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

</td>
</tr>
<tr>
<th>Результат</th>
<td>106,336</td>
<td>106,224</td>
</tr>
</tbody>
</table>
<p><strong>Вывод:</strong> использование пустых значений «сложных» типов (строки, массивы, объекты) ведёт к повышенному потреблению памяти. Использование <code>NULL</code> — самый оптимальный вариант.</p>
<h3><span class="codebox"><code class="php"><span class="kw3">is_null</span><span class="br0">&#40;</span><span class="br0">&#41;</span></code></span> или строгая проверка на <span class="codebox"><code class="php"><span class="kw4">NULL</span></code></span>?</h3>
<table class="bordered" style="width: 99%; table-layout:fixed">
<thead>
<tr>
<th style="width: 100px">&nbsp;</th>
<th style="width: 50%"><span class="codebox"><code class="php"><span class="kw3">is_null</span></code></span></th>
<th style="width: 50%">Строгое соответствие</th>
</tr>
</thead>
<tbody style="vertical-align: top">
<tr>
<th scope="row">Код</th>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65163">
        <div class="code php" id="p651code63">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="re0">$a</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">is_null</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

</td>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65164">
        <div class="code php" id="p651code64">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="re0">$a</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$a</span> <span class="sy0">===</span> <span class="kw4">NULL</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

</td>
</tr>
<tr>
<th>Результат</th>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65165">
        <div class="code text" id="p651code65">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a, 0<br />
&nbsp; &nbsp;3 &nbsp; &nbsp; 1 &nbsp;SEND_VAR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp;DO_FCALL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'is_null'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $1, -&gt;5<br />
&nbsp; &nbsp;4 &nbsp; &nbsp; 4 &nbsp;JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;5<br />
&nbsp; &nbsp;6 &nbsp; &nbsp; 5 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

</td>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65166">
        <div class="code text" id="p651code66">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a, 0<br />
&nbsp; &nbsp;3 &nbsp; &nbsp; 1 &nbsp;IS_IDENTICAL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1 &nbsp; &nbsp; &nbsp;$a, null<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1, -&gt;4<br />
&nbsp; &nbsp;4 &nbsp; &nbsp; 3 &nbsp;JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;4<br />
&nbsp; &nbsp;6 &nbsp; &nbsp; 4 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;5* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

</td>
</tr>
</tbody>
</table>
<p><strong>Вывод:</strong> проверка на строгое равенство NULL работает быстрее, в том числе из-за отсутствия необходимости вызова функции.</p>
<h3><span class="codebox"><code class="php"><span class="kw1">echo</span></code></span>: конкатенация или запятые?</h3>
<table class="bordered" style="width: 99%; table-layout:fixed">
<thead>
<tr>
<th style="width: 100px">&nbsp;</th>
<th style="width: 50%">Конкатенация</th>
<th style="width: 50%">Запятые</th>
</tr>
</thead>
<tbody style="vertical-align: top">
<tr>
<th scope="row">Код</th>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65167">
        <div class="code php" id="p651code67">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="kw1">echo</span> <span class="st_h">'Memory '</span> <span class="sy0">.</span> <span class="st_h">'usage '</span> <span class="sy0">.</span> <span class="st_h">'is '</span> <span class="sy0">.</span> <span class="kw3">memory_get_usage</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st0">&quot;<span class="es1">\n</span>&quot;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

</td>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65168">
        <div class="code php" id="p651code68">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="kw1">echo</span> <span class="st_h">'Memory '</span><span class="sy0">,</span> <span class="st_h">'usage '</span><span class="sy0">,</span> <span class="st_h">'is '</span><span class="sy0">,</span> <span class="kw3">memory_get_usage</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es1">\n</span>&quot;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

</td>
</tr>
<tr>
<th>Результат</th>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65169">
        <div class="code text" id="p651code69">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;CONCAT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~0 &nbsp; &nbsp; &nbsp;'Memory ', 'usage '<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp;CONCAT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1 &nbsp; &nbsp; &nbsp;~0, 'is ' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp;DO_FCALL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'memory_get_usage' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp;CONCAT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~3 &nbsp; &nbsp; &nbsp;~1, $2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4 &nbsp;CONCAT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~4 &nbsp; &nbsp; &nbsp;~3, '\n' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;5 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~4<br />
&nbsp; &nbsp;3 &nbsp; &nbsp; 6 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;7* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

</td>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65170">
        <div class="code text" id="p651code70">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Memory '<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'usage '<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'is '<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp;DO_FCALL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'memory_get_usage'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $0<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;5 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '\n'<br />
&nbsp; &nbsp;3 &nbsp; &nbsp; 6 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;7* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

</td>
</tr>
<tr>
<th scope="row">&nbsp;</th>
<td>
Memory usage is 106192
</td>
<td>
Memory usage is 106184
</td>
</tr>
</tbody>
</table>
<p><strong>Выводы:</strong> в очередной раз менее читабельный метод оказался лучшим — на этот раз в плане потребления памяти. И, как видим, PHP не догадался даже объединить строки вместе.</p>
<h3>Что быстрее: статический или динамический метод?</h3>
<table class="bordered" style="width: 99%; table-layout:fixed">
<thead>
<tr>
<th style="width: 100px">&nbsp;</th>
<th style="width: 50%">Динамический метод</th>
<th style="width: 50%">Статический метод</th>
</tr>
</thead>
<tbody style="vertical-align: top">
<tr>
<th scope="row">Код</th>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65171">
        <div class="code php" id="p651code71">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="kw2">class</span> A <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> test<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; <span class="re0">$a</span> <span class="sy0">=</span> <span class="kw2">new</span> A<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="re0">$a</span><span class="sy0">-&gt;</span><span class="me1">test</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

</td>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65172">
        <div class="code php" id="p651code72">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="kw2">class</span> A <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">static</span> <span class="kw2">function</span> test<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; <span class="re0">$a</span> <span class="sy0">=</span> <span class="kw2">new</span> A<span class="sy0">;</span><br />
&nbsp; &nbsp; A<span class="sy0">::</span><span class="me2">test</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

</td>
</tr>
<tr>
<th>Результат</th>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65173">
        <div class="code text" id="p651code73">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;NOP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;6 &nbsp; &nbsp; 1 &nbsp;ZEND_FETCH_CLASS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :1 &nbsp; &nbsp; &nbsp;'A' &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp;NEW &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$2 &nbsp; &nbsp; &nbsp;:1 &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp;DO_FCALL_BY_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a, $2 &nbsp; &nbsp;<br />
&nbsp; &nbsp;7 &nbsp; &nbsp; 5 &nbsp;ZEND_INIT_METHOD_CALL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$5 &nbsp; &nbsp; &nbsp;$a, 'test'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp;DO_FCALL_BY_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;8 &nbsp; &nbsp; 7 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;8* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

</td>
<td>
          
<div class="codebox">
    <div class="the_code" style="" id="p65174">
        <div class="code text" id="p651code74">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;NOP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;6 &nbsp; &nbsp; 1 &nbsp;ZEND_FETCH_CLASS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :1 &nbsp; &nbsp; &nbsp;'A' &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp;NEW &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$2 &nbsp; &nbsp; &nbsp;:1 &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp;DO_FCALL_BY_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a, $2 &nbsp; &nbsp;<br />
&nbsp; &nbsp;7 &nbsp; &nbsp; 5 &nbsp;ZEND_FETCH_CLASS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :5 &nbsp; &nbsp; &nbsp;'A' &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp;ZEND_INIT_STATIC_METHOD_CALL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; null, 'test'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;7 &nbsp;DO_FCALL_BY_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;8 &nbsp; &nbsp; 8 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;9* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

</td>
</tr>
</tbody>
</table>
<p><strong>Выводы:</strong> при прочих равных условиях, вызов статического метода на один опкод длиннее вызова динамического метода. Таким образом, если делать все методы класса, которые не используют <span class="codebox"><code class="php"><span class="re0">$this</span></code></span>, статическими, это приведёт к потреблению памяти.</p>
<p>Спички спичками, но сколько таких спичек экономится в мало-мальски сложном скрипте (таком, как <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a>). Пусть результат от одной сэкономленной спички ничтожно мал, но помноженный на количество таких потенциальных спичек во всём коде, становится весьма и весьма ощутимым, особенно на слабом железе.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/php/651-php-code-beauty-impacts-performance-part-2/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/php/651-php-code-beauty-impacts-performance-part-2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>PHP: красота кода сказывается на производительности</title>
		<link>http://blog.sjinks.pro/php/650-php-code-beauty-impacts-performance/</link>
		<comments>http://blog.sjinks.pro/php/650-php-code-beauty-impacts-performance/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 01:14:52 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[eAccelerator]]></category>
		<category><![CDATA[оптимизация]]></category>
		<category><![CDATA[производительность]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=650</guid>
		<description><![CDATA[Читабельный код выполняется медленнее Недавно я для себя открыл, что PHP не умеет оптимизировать код, а тут новый удар: оказывается, что красота кода отрицательно влияет на производительность. Как и в прошлый раз, для проверки гипотез использовался Vulcan Logic Disassembler. Сравнивались два куска кода: Тест №1: &#60;?php $a = true; if (true == $a) { print [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/php/650-php-code-beauty-impacts-performance/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Читабельный код выполняется медленнее</em></h2>
<p>Недавно я для себя открыл, что <a href="http://blog.sjinks.pro/php/638-byte-code-optimization-in-php/"><strong>PHP не умеет оптимизировать код</strong></a>, а тут новый удар: оказывается, что красота кода отрицательно влияет на <a href="http://blog.sjinks.pro/tag/performance/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  производительность">производительность</a>.<span id="more-650"></span></p>
<p>Как и в прошлый раз, для проверки гипотез использовался <a href="http://pecl.php.net/package/vld/">Vulcan Logic Disassembler</a>.</p>
<p>Сравнивались два куска кода:</p>
<p><strong>Тест №1:</strong></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p65087">
        <div class="code php" id="p650code87">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="re0">$a</span> <span class="sy0">=</span> <span class="kw4">true</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw4">true</span> <span class="sy0">==</span> <span class="re0">$a</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="nu0">1</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

<p>и абсолютно аналогичный по функциональности</p>
<p><strong>Тест №2:</strong></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p65088">
        <div class="code php" id="p650code88">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="re0">$a</span> <span class="sy0">=</span> <span class="kw4">true</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$a</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="nu0">1</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

<p>На выходе получилась такая картина.<br />
<strong>Для первого случая:</strong></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p65089">
        <div class="code text" id="p650code89">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;FETCH_CONSTANT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~0 &nbsp; &nbsp; &nbsp;'true'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a, ~0<br />
&nbsp; &nbsp;3 &nbsp; &nbsp; 2 &nbsp;FETCH_CONSTANT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~2 &nbsp; &nbsp; &nbsp;'true'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp;IS_EQUAL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~3 &nbsp; &nbsp; &nbsp;~2, $a<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~3, -&gt;8<br />
&nbsp; &nbsp;4 &nbsp; &nbsp; 5 &nbsp;PRINT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;~4 &nbsp; &nbsp; &nbsp;1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp;FREE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~4<br />
&nbsp; &nbsp;5 &nbsp; &nbsp; 7 &nbsp;JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;8<br />
&nbsp; &nbsp;6 &nbsp; &nbsp; 8 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;9* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

<p><strong>Для второго случая:</strong></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p65090">
        <div class="code text" id="p650code90">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;FETCH_CONSTANT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~0 &nbsp; &nbsp; &nbsp;'true'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a, ~0<br />
&nbsp; &nbsp;3 &nbsp; &nbsp; 2 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a, -&gt;6<br />
&nbsp; &nbsp;4 &nbsp; &nbsp; 3 &nbsp;PRINT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;~2 &nbsp; &nbsp; &nbsp;1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4 &nbsp;FREE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~2<br />
&nbsp; &nbsp;5 &nbsp; &nbsp; 5 &nbsp;JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;6<br />
&nbsp; &nbsp;6 &nbsp; &nbsp; 6 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;7* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

<p>Видим, что в первом случае <a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a>, как мы его и попросили, честно сравнил <span class="codebox"><code class="php"><span class="kw4">true</span></code></span> c <span class="codebox"><code class="php"><span class="re0">$a</span></code></span> и проверил, равен ли результат сравнения нулю или нет. Во втором же случае PHP просто проверил, равно ли <span class="codebox"><code class="php"><span class="re0">$a</span></code></span> нулю, сэкономив два опкода.</p>
<p>Будучи любопытным, я заменил проверку на равенство <span class="codebox"><code class="php"><span class="kw4">true</span></code></span> проверкой на неравенство <span class="codebox"><code class="php"><span class="kw4">false</span></code></span>. Хрен редьки не слаще: те же 9 опкодов:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p65091">
        <div class="code text" id="p650code91">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;FETCH_CONSTANT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~0 &nbsp; &nbsp; &nbsp;'true'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a, ~0<br />
&nbsp; &nbsp;3 &nbsp; &nbsp; 2 &nbsp;FETCH_CONSTANT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~2 &nbsp; &nbsp; &nbsp;'false'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp;IS_NOT_EQUAL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~3 &nbsp; &nbsp; &nbsp;~2, $a<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~3, -&gt;8<br />
&nbsp; &nbsp;4 &nbsp; &nbsp; 5 &nbsp;PRINT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;~4 &nbsp; &nbsp; &nbsp;1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp;FREE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~4<br />
&nbsp; &nbsp;5 &nbsp; &nbsp; 7 &nbsp;JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;8<br />
&nbsp; &nbsp;6 &nbsp; &nbsp; 8 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;9* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

<p>Попутно выяснил, что те, кто говорят, что <span class="codebox"><code class="php"><span class="kw1">echo</span></code></span> быстрее, чем <span class="codebox"><code class="php"><span class="kw1">print</span></code></span>, правы. Я поменял <span class="codebox"><code class="php"><span class="kw1">print</span> <span class="nu0">1</span></code></span>; на <span class="codebox"><code class="php"><span class="kw1">echo</span> <span class="nu0">1</span></code></span>, в результате код программы сократился на один опкод:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p65092">
        <div class="code text" id="p650code92">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;FETCH_CONSTANT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~0 &nbsp; &nbsp; &nbsp;'true'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a, ~0<br />
&nbsp; &nbsp;3 &nbsp; &nbsp; 2 &nbsp;FETCH_CONSTANT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~2 &nbsp; &nbsp; &nbsp;'false'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp;IS_NOT_EQUAL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~3 &nbsp; &nbsp; &nbsp;~2, $a<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~3, -&gt;7<br />
&nbsp; &nbsp;4 &nbsp; &nbsp; 5 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp;5 &nbsp; &nbsp; 6 &nbsp;JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;7<br />
&nbsp; &nbsp;6 &nbsp; &nbsp; 7 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;8* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

<p>Затем я решил проверить, что лучше: <span class="codebox"><code class="php"><span class="kw1">switch</span></code></span> или спагетти из <span class="codebox"><code class="php"><span class="kw1">if</span></code></span>/<span class="codebox"><code class="php"><span class="kw1">elseif</span></code></span>.</p>
<p><strong>Тест №3</strong></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p65093">
        <div class="code php" id="p650code93">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="re0">$a</span> <span class="sy0">=</span> <span class="nu0">5</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$a</span> <span class="sy0">==</span> 1<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">echo</span> <span class="nu0">1</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">elseif</span> <span class="br0">&#40;</span><span class="re0">$a</span> <span class="sy0">==</span> 2<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">echo</span> <span class="nu0">2</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">elseif</span> <span class="br0">&#40;</span><span class="re0">$a</span> <span class="sy0">==</span> 3<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">echo</span> <span class="nu0">3</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">echo</span> <span class="st0">&quot;:-(&quot;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

<p><strong>Результат:</strong></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p65094">
        <div class="code text" id="p650code94">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a, 5<br />
&nbsp; &nbsp;3 &nbsp; &nbsp; 1 &nbsp;IS_EQUAL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1 &nbsp; &nbsp; &nbsp;$a, 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1, -&gt;5<br />
&nbsp; &nbsp;4 &nbsp; &nbsp; 3 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp;5 &nbsp; &nbsp; 4 &nbsp;JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;14<br />
&nbsp; &nbsp;6 &nbsp; &nbsp; 5 &nbsp;IS_EQUAL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~2 &nbsp; &nbsp; &nbsp;$a, 2<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~2, -&gt;9<br />
&nbsp; &nbsp;7 &nbsp; &nbsp; 7 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2<br />
&nbsp; &nbsp;8 &nbsp; &nbsp; 8 &nbsp;JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;14<br />
&nbsp; &nbsp;9 &nbsp; &nbsp; 9 &nbsp;IS_EQUAL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~3 &nbsp; &nbsp; &nbsp;$a, 3<br />
&nbsp; &nbsp; &nbsp; &nbsp; 10 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~3, -&gt;13<br />
&nbsp; 10 &nbsp; &nbsp;11 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3<br />
&nbsp; 11 &nbsp; &nbsp;12 &nbsp;JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;14<br />
&nbsp; 13 &nbsp; &nbsp;13 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ':-('<br />
&nbsp; 15 &nbsp; &nbsp;14 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; 15* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

<p><strong>Тест №4</strong></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p65095">
        <div class="code php" id="p650code95">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="re0">$a</span> <span class="sy0">=</span> <span class="nu0">5</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">switch</span> <span class="br0">&#40;</span><span class="re0">$a</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> 1<span class="sy0">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">echo</span> <span class="nu0">1</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> 2<span class="sy0">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">echo</span> <span class="nu0">2</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> 3<span class="sy0">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">echo</span> <span class="nu0">3</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">default</span><span class="sy0">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">echo</span> <span class="st0">&quot;:-(&quot;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

<p><strong>Результат:</strong></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p65096">
        <div class="code text" id="p650code96">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a, 5<br />
&nbsp; &nbsp;4 &nbsp; &nbsp; 1 &nbsp;CASE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1 &nbsp; &nbsp; &nbsp;$a, 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1, -&gt;6<br />
&nbsp; &nbsp;5 &nbsp; &nbsp; 3 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp;6 &nbsp; &nbsp; 4 &nbsp;BRK &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1<br />
&nbsp; &nbsp;7 &nbsp; &nbsp; 5* JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;8<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp;CASE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1 &nbsp; &nbsp; &nbsp;$a, 2<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;7 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1, -&gt;11<br />
&nbsp; &nbsp;8 &nbsp; &nbsp; 8 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2<br />
&nbsp; &nbsp;9 &nbsp; &nbsp; 9 &nbsp;BRK &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1<br />
&nbsp; 10 &nbsp; &nbsp;10* JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;13<br />
&nbsp; &nbsp; &nbsp; &nbsp; 11 &nbsp;CASE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1 &nbsp; &nbsp; &nbsp;$a, 3<br />
&nbsp; &nbsp; &nbsp; &nbsp; 12 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~1, -&gt;16<br />
&nbsp; 11 &nbsp; &nbsp;13 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3<br />
&nbsp; 12 &nbsp; &nbsp;14 &nbsp;BRK &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1<br />
&nbsp; 13 &nbsp; &nbsp;15* JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;17<br />
&nbsp; &nbsp; &nbsp; &nbsp; 16 &nbsp;JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;20<br />
&nbsp; 14 &nbsp; &nbsp;17 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ':-('<br />
&nbsp; 15 &nbsp; &nbsp;18 &nbsp;BRK &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1<br />
&nbsp; 16 &nbsp; &nbsp;19* JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;21<br />
&nbsp; &nbsp; &nbsp; &nbsp; 20 &nbsp;JMP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;17<br />
&nbsp; 17 &nbsp; &nbsp;21 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; 22* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

<p>Результат для <span class="codebox"><code class="php"><span class="kw1">switch</span></code></span> хоть и более читаемый, но оказался в полтора раза хуже результата для <span class="codebox"><code class="php"><span class="kw1">if</span></code></span>. Sad but true.</p>
<p>После этого я собрал (с поддержкой оптимизатора) и поставил <a href="http://blog.sjinks.pro/tag/eaccelerator/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  eAccelerator">eAccelerator</a> и повторил тесты.</p>
<p><strong>Тест №1</strong> и <strong>тест №2</strong> дали одинаковый результат:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p65097">
        <div class="code text" id="p650code97">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a, true<br />
&nbsp; &nbsp;3 &nbsp; &nbsp; 1 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a, -&gt;3<br />
&nbsp; &nbsp;4 &nbsp; &nbsp; 2 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp;6 &nbsp; &nbsp; 3 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

<p>Что характерно, eAccelerator самостоятельно преобразовал <span class="codebox"><code class="php"><span class="kw1">print</span></code></span> в <span class="codebox"><code class="php"><span class="kw1">echo</span></code></span>. Лапочка.</p>
<p>Для <strong>теста №3</strong> результат остался неизменным: там, собственно, нечего оптимизировать.</p>
<p>А результаты <strong>теста №4</strong> впечатлили:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p65098">
        <div class="code text" id="p650code98">
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a, 5<br />
&nbsp; &nbsp;4 &nbsp; &nbsp; 1 &nbsp;CASE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~0 &nbsp; &nbsp; &nbsp;$a, 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~0, -&gt;5<br />
&nbsp; &nbsp;5 &nbsp; &nbsp; 3 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; 17 &nbsp; &nbsp; 4 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp;7 &nbsp; &nbsp; 5 &nbsp;CASE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~0 &nbsp; &nbsp; &nbsp;$a, 2<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~0, -&gt;9<br />
&nbsp; &nbsp;8 &nbsp; &nbsp; 7 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2<br />
&nbsp; 17 &nbsp; &nbsp; 8 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; 10 &nbsp; &nbsp; 9 &nbsp;CASE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~0 &nbsp; &nbsp; &nbsp;$a, 3<br />
&nbsp; &nbsp; &nbsp; &nbsp; 10 &nbsp;JMPZ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~0, -&gt;13<br />
&nbsp; 11 &nbsp; &nbsp;11 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3<br />
&nbsp; 17 &nbsp; &nbsp;12 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; 14 &nbsp; &nbsp;13 &nbsp;ECHO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ':-('<br />
&nbsp; 17 &nbsp; &nbsp;14 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; 15* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

<p>На выходе получили результат, который по эффективности аналогичен коду из <span class="codebox"><code class="php"><span class="kw1">if</span></code></span>!</p>
<p>Поэтому в заключение скажу: ставьте eAccelerator и будет всем счастье!</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/php/650-php-code-beauty-impacts-performance/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/php/650-php-code-beauty-impacts-performance/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>SJ Hook Profiler — плагин для измерения производительности хуков</title>
		<link>http://blog.sjinks.pro/wordpress/plugins/642-sj-hook-profiler/</link>
		<comments>http://blog.sjinks.pro/wordpress/plugins/642-sj-hook-profiler/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 23:01:11 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[bbPress]]></category>
		<category><![CDATA[Плагины WordPress]]></category>
		<category><![CDATA[SJ Hook Profiler]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[оптимизация]]></category>
		<category><![CDATA[плагин]]></category>
		<category><![CDATA[производительность]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=642</guid>
		<description><![CDATA[Поиск слабых мест в WordPress и bbPress Сразу оговорюсь, что речь пойдёт совсем не о боксе, а о WordPress и bbPress. Разработчики плагинов WordPress и bbPress используют две функции для расширения функциональности WordPress/bbPress: это add_action() и add_filter(). Первая служит для установки обработчика некоторого события, вторая — для установки фильтра. Под хуком подразумевается обобщённое понятие (либо фильтр, [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/plugins/642-sj-hook-profiler/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Поиск слабых мест в <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a> и <a href="http://blog.sjinks.pro/tag/bbpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  bbPress">bbPress</a></em></h2>
<p>Сразу оговорюсь, что речь пойдёт совсем не о боксе, а о WordPress и bbPress.</p>
<p>Разработчики плагинов WordPress и bbPress используют две функции для расширения функциональности WordPress/bbPress: это <span class="codebox"><code class="php">add_action<span class="br0">&#40;</span><span class="br0">&#41;</span></code></span> и <span class="codebox"><code class="php">add_filter<span class="br0">&#40;</span><span class="br0">&#41;</span></code></span>. Первая служит для установки обработчика некоторого события, вторая — для установки фильтра. Под <dfn>хуком</dfn> подразумевается обобщённое понятие (либо фильтр, либо обработчик).</p>
<p>Как показывает практика, б<em>о</em>льшая часть времени генерации страницы уходит именно на вызов обработчиков и фильтров. И когда возникает вопрос: почему время генерации страницы такое большое, а запроса всего три, и они выполняются за сотые доли секунды, на помощь приходит данный <a href="http://blog.sjinks.pro/tag/plugin/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  плагин">плагин</a>.<span id="more-642"></span></p>
<p>В отличие от WP Tuner, которому явно нужно указывать, какие события нужно профилировать, <a href="http://blog.sjinks.pro/tag/sj-hook-profiler/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  SJ Hook Profiler">SJ Hook Profiler</a> автоматически определяет <em>все</em> используемые хуки и устанавливает обработчики, измеряющие их время работы. На выходе получается что-то вида данной таблицы:</p>
<table class="hookdebug">
<thead>
<tr>
<th>Hook Name</th>
<th>Total Time</th>
<th>Invocations</th>
<th>Average Time</th>
</tr>
</thead>
<tbody>
<tr>
<td>pre_option_gmt_offset</td>
<td>0.000169</td>
<td>1</td>
<td>0.000169</td>
</tr>
<tr>
<td>option_blog_charset</td>
<td>0.000405</td>
<td>11</td>
<td>0.000037</td>
</tr>
<tr>
<td>plugins_loaded</td>
<td>0.014295</td>
<td>1</td>
<td>0.014295</td>
</tr>
<tr>
<td>option_siteurl</td>
<td>0.000810</td>
<td>26</td>
<td>0.000031</td>
</tr>
<tr>
<td>option_home</td>
<td>0.004852</td>
<td>160</td>
<td>0.000030</td>
</tr>
<tr>
<td>sanitize_comment_cookies</td>
<td>0.000117</td>
<td>1</td>
<td>0.000117</td>
</tr>
<tr>
<td>option_category_base</td>
<td>0.000029</td>
<td>1</td>
<td>0.000029</td>
</tr>
<tr>
<td>option_tag_base</td>
<td>0.000027</td>
<td>1</td>
<td>0.000027</td>
</tr>
<tr>
<td>setup_theme</td>
<td>0.000030</td>
<td>1</td>
<td>0.000030</td>
</tr>
<tr>
<td>wp_default_scripts</td>
<td>0.001951</td>
<td>1</td>
<td>0.001951</td>
</tr>
<tr>
<td>set_current_user</td>
<td>0.000114</td>
<td>1</td>
<td>0.000114</td>
</tr>
<tr>
<td>init</td>
<td>0.011603</td>
<td>1</td>
<td>0.011603</td>
</tr>
<tr>
<td>widgets_init</td>
<td>0.003384</td>
<td>1</td>
<td>0.003384</td>
</tr>
<tr>
<td>wp_default_styles</td>
<td>0.000349</td>
<td>1</td>
<td>0.000349</td>
</tr>
<tr>
<td>query_vars</td>
<td>0.000036</td>
<td>1</td>
<td>0.000036</td>
</tr>
<tr>
<td>sanitize_title</td>
<td>0.001518</td>
<td>17</td>
<td>0.000089</td>
</tr>
<tr>
<td>posts_where</td>
<td>0.000033</td>
<td>1</td>
<td>0.000033</td>
</tr>
<tr>
<td>the_posts</td>
<td>0.000127</td>
<td>1</td>
<td>0.000127</td>
</tr>
<tr>
<td>template_redirect</td>
<td>0.000541</td>
<td>1</td>
<td>0.000541</td>
</tr>
<tr>
<td>bloginfo</td>
<td>0.002297</td>
<td>8</td>
<td>0.000287</td>
</tr>
<tr>
<td>term_name</td>
<td>0.000621</td>
<td>2</td>
<td>0.000310</td>
</tr>
<tr>
<td>term_description</td>
<td>0.000982</td>
<td>2</td>
<td>0.000491</td>
</tr>
<tr>
<td>single_post_title</td>
<td>0.000468</td>
<td>2</td>
<td>0.000234</td>
</tr>
<tr>
<td>wp_title</td>
<td>0.000747</td>
<td>2</td>
<td>0.000373</td>
</tr>
<tr>
<td>wp_head</td>
<td>0.020773</td>
<td>1</td>
<td>0.020773</td>
</tr>
<tr>
<td>comments_open</td>
<td>0.000373</td>
<td>4</td>
<td>0.000093</td>
</tr>
<tr>
<td>the_title</td>
<td>0.011747</td>
<td>46</td>
<td>0.000255</td>
</tr>
<tr>
<td>wp_print_styles</td>
<td>0.000175</td>
<td>2</td>
<td>0.000088</td>
</tr>
<tr>
<td>style_loader_src</td>
<td>0.000330</td>
<td>9</td>
<td>0.000037</td>
</tr>
<tr>
<td>wp_print_scripts</td>
<td>0.000440</td>
<td>1</td>
<td>0.000440</td>
</tr>
<tr>
<td>print_scripts_array</td>
<td>0.000050</td>
<td>1</td>
<td>0.000050</td>
</tr>
<tr>
<td>wp_list_pages</td>
<td>0.000305</td>
<td>1</td>
<td>0.000305</td>
</tr>
<tr>
<td>the_author</td>
<td>0.000534</td>
<td>2</td>
<td>0.000267</td>
</tr>
<tr>
<td>the_content</td>
<td>1.004469</td>
<td>1</td>
<td>1.004469</td>
</tr>
<tr>
<td>comment_text</td>
<td>0.001105</td>
<td>1</td>
<td>0.001105</td>
</tr>
<tr>
<td>pings_open</td>
<td>0.000087</td>
<td>1</td>
<td>0.000087</td>
</tr>
<tr>
<td>comment_form</td>
<td>0.007084</td>
<td>1</td>
<td>0.007084</td>
</tr>
<tr>
<td>widget_title</td>
<td>0.001137</td>
<td>4</td>
<td>0.000284</td>
</tr>
<tr>
<td>list_cats</td>
<td>0.004768</td>
<td>22</td>
<td>0.000217</td>
</tr>
<tr>
<td>wp_footer</td>
<td>0.009798</td>
<td>1</td>
<td>0.009798</td>
</tr>
<tr>
<td>wp_print_footer_scripts</td>
<td>0.000115</td>
<td>1</td>
<td>0.000115</td>
</tr>
</tbody>
</table>
<p>Из таблицы видно, что слабое место — это вызов фильтра <code>the_content</code> (вызов более одной секунды), и копать нужно именно в сторону оптимизации фильтров <code>the_content</code>. Пока не поддерживается профилирование каждого обработчика (то есть делаются замеры до вызова первого обработчика <code>the_content</code> и после вызова последнего), но это в планах.</p>
<p>Одна из особенностей плагина — поддержка как WordPress, так и bbPress (правда, пришлось немного поколдовать).</p>
<p>По умолчанию плагин активен только для администратора (WordPress) и Key Master (bbPress); изменить это можно, повесив обработчик на фильтр <code>enable_hook_profiler</code> (должен вернуть <span class="codebox"><code class="php"><span class="kw4">true</span></code></span>, если профайлер нужно активировать и <span class="codebox"><code class="php"><span class="kw4">false</span></code></span> в противном случае).</p>
<p><strong><a href="http://d.sjinks.pro/wordpress/sj-hook-profiler-0.1.zip">Скачать плагин SJ Hook Profiler 0.1</a></strong>.<br />
<strong><a href="http://d.sjinks.pro/wordpress/sj-hook-profiler-0.2.zip">Скачать плагин SJ Hook Profiler 0.2</a></strong>.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/plugins/642-sj-hook-profiler/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/plugins/642-sj-hook-profiler/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Оптимизация байт-кода в PHP</title>
		<link>http://blog.sjinks.pro/php/638-byte-code-optimization-in-php/</link>
		<comments>http://blog.sjinks.pro/php/638-byte-code-optimization-in-php/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 19:02:59 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Engine]]></category>
		<category><![CDATA[оптимизация]]></category>
		<category><![CDATA[производительность]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=638</guid>
		<description><![CDATA[Отсутствие всякой оптимизации кода в PHP Я давно задавался вопросом, насколько «умным» является интерпретатор PHP в том, что касается оптимизации. В частности, меня всегда интересовала поддержка исключения неиспользуемого кода (известная как dead code elimination) и распространение константных значений (constant propagation). И теперь, когда я вплотную занялся изучением внутренностей Zend Engine, у меня такая возможность появилась. [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/php/638-byte-code-optimization-in-php/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Отсутствие всякой оптимизации кода в <a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a></em></h2>
<p>Я давно задавался вопросом, насколько «умным» является интерпретатор PHP в том, что касается оптимизации. В частности, меня всегда интересовала поддержка исключения неиспользуемого кода (известная как <dfn>dead code elimination</dfn>) и распространение константных значений (<dfn>constant propagation</dfn>). И теперь, когда я вплотную занялся изучением внутренностей <a href="http://blog.sjinks.pro/tag/zend-engine/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Zend Engine">Zend Engine</a>, у меня такая возможность появилась.<span id="more-638"></span></p>
<p>Я взял простой тестовый файл:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p638101">
        <div class="code php" id="p638code101">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="re0">$a</span> <span class="sy0">=</span> 2 <span class="sy0">*</span> <span class="nu0">2</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="re0">$a</span> <span class="sy0">=</span> 3 <span class="sy0">*</span> <span class="nu0">3</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">print</span> <span class="re0">$a</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

<p>В идеале выражения <span class="codebox"><code class="php"><span class="nu0">2</span><span class="sy0">*</span><span class="nu0">2</span></code></span> и <span class="codebox"><code class="php"><span class="nu0">3</span><span class="sy0">*</span><span class="nu0">3</span></code></span> должны вычисляться на этапе компиляции, выражение <span class="codebox"><code class="php"><span class="re0">$a</span> <span class="sy0">=</span> 2 <span class="sy0">*</span> <span class="nu0">2</span><span class="sy0">;</span></code></span> выбрасываться за ненужностью (ибо его вычисление не связано с побочными эффектами, а результат не используется), а <span class="codebox"><code class="php"><span class="kw1">print</span> <span class="re0">$a</span><span class="sy0">;</span></code></span> заменяться <span class="codebox"><code class="php"><span class="kw1">print</span> <span class="nu0">9</span><span class="sy0">;</span></code></span> (ибо значение <span class="codebox"><code class="php"><span class="re0">$a</span></code></span> известно).</p>
<p><del datetime="2009-09-25T00:10:37+00:00">Результирующий код «дизассемблировался» самопальным zend-расширением (которое пока за сыростью его исходников в общий доступ выкладывать не буду).</del><br />
Результирующий код «дизассемблировался» при помощи замечательного расширения <a href="http://pecl.php.net/package/vld/">Vulcan Logic Disassembler</a>, спасшего меня от изобретения очередного велосипеда.</p>
<p>На выходе получился такой результат:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p638102">
        <div class="code text" id="p638code102">
line &nbsp; &nbsp; # &nbsp;op &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ext &nbsp;return &nbsp;operands<br />
-------------------------------------------------------------------------------<br />
&nbsp; &nbsp;2 &nbsp; &nbsp; 0 &nbsp;MUL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;~0 &nbsp; &nbsp; &nbsp;2, 2<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a, ~0<br />
&nbsp; &nbsp;3 &nbsp; &nbsp; 2 &nbsp;MUL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;~2 &nbsp; &nbsp; &nbsp;3, 3<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp;ASSIGN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $a, ~2<br />
&nbsp; &nbsp;4 &nbsp; &nbsp; 4 &nbsp;PRINT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;~4 &nbsp; &nbsp; &nbsp;$a<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;5 &nbsp;FREE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~4<br />
&nbsp; &nbsp;5 &nbsp; &nbsp; 6 &nbsp;RETURN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;7* ZEND_HANDLE_EXCEPTION
        </div>
    </div>
</div>

<p>Из чего следует, что все константные выражения вычисляются непосредственно в ходе выполнения кода; как следствие, константы, получаемые в ходе вычисления константных выражений, не распространяются. И мёртвый код не удаляется. Обидно.</p>
<p>Поэтому когда <a href="http://blog.sjinks.pro/humour/76-programmers-russian-indian-chinese-canadian/">китайские программисты</a> наблюдают дао присваивания (<span class="codebox"><code class="php"><span class="re0">$a</span> <span class="sy0">=</span> <span class="re0">$a</span><span class="sy0">;</span></code></span>), это вредит производительности.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/php/638-byte-code-optimization-in-php/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/php/638-byte-code-optimization-in-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

