<?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>潘锦的空间 &#187; 循环</title>
	<atom:link href="https://www.phppan.com/tag/%e5%be%aa%e7%8e%af/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.phppan.com</link>
	<description>SaaS SaaS架构 团队管理 技术管理 技术架构 PHP 内核 扩展 项目管理</description>
	<lastBuildDate>Sat, 04 Apr 2026 01:19:58 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=3.9.40</generator>
	<item>
		<title>奇技淫巧一：循环加速</title>
		<link>https://www.phppan.com/2011/01/craft-1-cycle/</link>
		<comments>https://www.phppan.com/2011/01/craft-1-cycle/#comments</comments>
		<pubDate>Tue, 04 Jan 2011 04:24:39 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[奇技淫巧]]></category>
		<category><![CDATA[循环]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=1210</guid>
		<description><![CDATA[奇技淫巧一：循环加速 循环通常是程序性能问题的多发地段。优化某些循环能极大的提高某段程序的性能。 以下的测试环 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>奇技淫巧一：循环加速<br />
循环通常是程序性能问题的多发地段。优化某些循环能极大的提高某段程序的性能。<br />
以下的测试环境为：win xampp1.7.3  PHP5.3.1<br />
<strong>【数组长度】</strong><br />
也许，maybe，可能，你看到如下类似的代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?PHP</span>
<span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">range</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1000000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$start</span> <span style="color: #339933;">=</span> xdebug_time_index<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>	<span style="color: #666666; font-style: italic;">//	关注点在这行</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$end</span> <span style="color: #339933;">=</span> xdebug_time_index<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$end</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$start</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>以上的程序运行在我的电脑上基本上是3.3秒到3.4秒的样子。<br />
如果我们把count($data)的计算提前到循环前，以局部变量在循环中迭代。如下所示代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?PHP</span>
<span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">range</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1000000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$start</span> <span style="color: #339933;">=</span> xdebug_time_index<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$len</span> <span style="color: #339933;">=</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>	<span style="color: #666666; font-style: italic;">//	其实局部变量是很快的。</span>
<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$len</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$end</span> <span style="color: #339933;">=</span> xdebug_time_index<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$end</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$start</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>在同样的环境下运行，基本上是0.32到0.4秒。<br />
对比一下，整整一个数量级的提升。只是优化了一点，性能有如此大的提升。对于这样的操作我们需要在平时注意，养成习惯。虽然PHP内部取数组的长度是从Hash Table中直接取的count值。可是这个相对于局部变量，在性能上还是有较大差别的。<br />
这里想到一个点，如果是HTML中使用JS取DOM集合，然后计算DOM的长度，此时如果有增加或删除节点，可能最后得到的结果并不是你要的那个结果。<br />
<strong>【计数变量】</strong><br />
和数组长度一样，计数变量也是一个在循环中每次迭代都会使用的变量。如果我们优化这个点，此时性能上应该也有部分提高。如下所示代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?PHP</span>
<span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">range</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1000000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$start</span> <span style="color: #339933;">=</span> xdebug_time_index<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">--;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>	<span style="color: #666666; font-style: italic;">//	我是关注点所在行</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$end</span> <span style="color: #339933;">=</span> xdebug_time_index<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$end</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$start</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>以上的代码将计数变量从大到小递减，当为0时自动停止。从而将判断语句和计数加1两条语句变成了一条语句。<br />
最后的运行时间大概为0.26到0.27秒。与前面的0.3到0.4秒，又有了大约30%的提升。</p>
<p><strong>只是，只是这些是针对for语句，在PHP中我们还有foreach。</strong><br />
<strong>【foreach】</strong><br />
将上面的for语句换成foreach，如下所示代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">range</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1000000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$start</span> <span style="color: #339933;">=</span> xdebug_time_index<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$end</span> <span style="color: #339933;">=</span> xdebug_time_index<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$end</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$start</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>运行时间为：0.11~0.13秒，也许此时我们应该去内核里面看下为什么了，只是这不是今天的重点。嘿嘿<br />
结果已经很明显了，如果可以，我们还是用foreach吧。<br />
<strong>【循环展开】</strong><br />
在《编程珠玑》中介绍了这样一种方案。只是他是针对特定的数组查找的问题。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">range</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1000005</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$start</span> <span style="color: #339933;">=</span> xdebug_time_index<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$len</span> <span style="color: #339933;">=</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$left</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$len</span> <span style="color: #339933;">%</span> <span style="color: #cc66cc;">8</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$left</span><span style="color: #339933;">--</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$i</span><span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$len</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">+=</span><span style="color: #cc66cc;">8</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$t</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$t</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$t</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$t</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$t</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$t</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">5</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$t</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">6</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$t</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">7</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$end</span> <span style="color: #339933;">=</span> xdebug_time_index<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$end</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$start</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>以上的方法运行时间为0.3多一些，这和前面的方法类似，但是需要考虑到这里多了8个赋值语句。如果去掉这8个赋值语句，其时间为0.04秒。</p>
<p><strong>以上的一些方法只是针对数量级比较大的数组，此时一些微小的优化都会产生巨大的能量。平时中，也许我们使用foreach就足够了。</strong></p>
<p><strong>【纠结的轮子】</strong><br />
最开始生成一百万的数组使用的是如下方式：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">1000005</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$i</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>纠结的轮子！</p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2011/01/craft-1-cycle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
