Home >php教程 >php手册 >php中foreach和while循环的区别比较

php中foreach和while循环的区别比较

WBOY
WBOYOriginal
2016-06-13 10:16:42905browse

foreach和while在php中都循环,那么foreach和while循环之间他们的区别是什么,那个性能会更好一些,下面我来给大家介绍foreach和while循环区别与性能比较,有需要了解的同学可参考。

在while循环里,Perl会读入一行输入,把它存入某个变量并且执行循环主体。然后,它再回头去找其他的输入行。

在foreach循环中,整行输入操作符会在列表上下文中执行(因为foreach需要逐行处理列表的内容)。在循环开始执行之前,它必须先将输入全部读进来。

当输入大容量的文件时,使用foreach会占用大量的内存。两者的差异会十分明显。因此,最好的做法,通常是尽量使用while循环的简写,让它每次处理一行。

下面是一些资料:

当你想重复执行某些语句或语段时,依据当前不同的任务,C#提供4个不同的循环语句选择给你使用:
。for 语句
。foreach 语句
。while 语句
。do 语句

1.for

当你预先知道一个内含语句应要执行多少次时,for 语句特别有用。当条件为真时,常规语法允许重复地执行内含语句(和循环表达式):

for (初始化;条件;循环) 内含语句

请注意,初始化、条件和循环都是可选的。如果忽略了条件,你就可以产生一个死循环,要用到跳转语句(break 或goto)才能退出。

 代码如下 复制代码

for (;;)
{
break; // 由于某些原因
}

另外一个重点是,你可以同时加入多条由逗号隔开的语句到for循环的所有三个参数。例如,你可以初始化两个变量、拥有三个条件语句,并重复4个变量。

2.foreach

已经在Visual Basic 语言中存在了很久的一个功能是,通过使用For Each 语句收集枚举。C#通过foreach 语句,也有一个用来收集枚举的命令:

foreach(表达式中的类型标识符) 内含语句

循环变量由类型和标识符声明,且表达式与收集相对应。循环变量代表循环正在为之运行的收集元素。

3.while

当你想执行一个内含语句0次或更多次时,while语句正是你所盼望的:

while (条件) 内含语句

条件语句——它也是一个布尔表达式 ——控制内含语句被执行的次数。你可以使用 break 和continue语句来控制while语句中的执行语句,它的运行方式同在for语句中的完全相同。

4,do

C#最后可利用的循环语句是do语句。它与while语句十分相似,仅当经过最初的循环之后,条件才被验证。

 代码如下 复制代码

do
{
内含语句
}
while (条件);

do语句保证内含语句至少被执行过一次,而且只要条件求值等于真,它们继续被执行。通过使用break语句,你可以迫使运行退出 do 语块。如果你想跳过这一次循环,使用continue语句。


性能对比

foreach是对数组副本进行操作(通过拷贝数组),而while则通过移动数组内部指标进行操作,一般逻辑下认为,while应该比foreach快(因为foreach在开始执行的时候首先把数组复制进去,而while直接移动内部指标。),但结果刚刚相反。
在循环里进行的是数组“读”操作,则foreach比while快:

 代码如下 复制代码
foreach ($array as $value) {
echo $value;
}
while (list($key) = each($array)) {
echo $array[$key];
}

在循环里进行的是数组“写”操作,则while比foreach快:

 代码如下 复制代码
foreach ($array as $key => $value) {
echo $array[$key] = $value . '...';
}
while (list($key) = each($array)) {
$array[$key] = $array[$key] . '...';
}


下面先让我们来测试一下共同遍历一个有50000个下标的一维数组所耗的时间:

测试平台:
CPU:P-M 725
内存:512M
硬盘:40G 5400转
OS:Windows xp SP2
WEB:apache 2.0.54  php5.0.4

测试代码:

 代码如下 复制代码

/*
  * @ Author: Lilov
  * @ Homepage: www.bKjia.c0m
  * @ E-mail: zhongjiechao@gmail.com
  *
  */

$arr = array();
for($i = 0; $i $arr[] = $i*rand(1000,9999);
}

function GetRunTime()
{
list($usec,$sec)=exp lode(" ",microtime());
return ((float)$usec+(float)$sec);
}
######################################
$time_start = GetRunTime();

for($i = 0; $i $str .= $arr[$i];
}

$time_end = GetRunTime();
$time_used = $time_end - $time_start;

echo 'Used time of for:'.round($time_used, 7).'(s)

';
unset($str, $time_start, $time_end, $time_used);
######################################
$time_start = GetRunTime();

while(list($key, $val) = each($arr)){
$str .= $val;
}

$time_end = GetRunTime();
$time_used = $time_end - $time_start;

echo 'Used time of while:'.round($time_used, 7).'(s)

';

unset($str, $key, $val, $time_start, $time_end, $time_used);
######################################
$time_start = GetRunTime();

foreach($arr as $key => $val){
$str .= $val;
}

$time_end = GetRunTime();
$time_used = $time_end - $time_start;
echo 'Used time of foreach:'.round($time_used, 7).'(s)

';
######################################

?>

测试结果:

将三次测试结果求平均值:
分别对应for、while、foreach
0.1311650
0.1666853
0.1237440

经过反复多次测试,结果表明,对于遍历同样一个数组,foreach速度最快,最慢的则是while。foreach比while大约快20% ~ 30%左右。随后再把数组下标添加到500000、5000000测试结果也一样。但从原理上来看,foreach是对数组副本实行操作(通过拷贝数组),而while则通过移动数组内部指标实行操作,一般逻辑下认为,while应该比foreach快(因为foreach在开始执行的时候首先把数组复制进去,而while直接移动内部指标。),但结果刚刚相反。原由应该是,foreach是PHP内部实现,而while是通用的循环结构。


总结:通常认为,foreach涉及到值复制,一定会比while慢,但实际上,如果仅仅是在循环里进行数组的读操作,那么foreach是很 快的,这是因为PHP采用的复制机制是“引用计数,写时复制”,也就是说,即便在PHP里复制一个变量,最初的形式从根本上说其实 仍然是引用的形式,只有当变量的内容发生变化时,才会出现真正的复制,之所以这么做是出于节省内存消耗得目的,同时也提升了 复制的效率。这样看来,foreach的高效读操作就不难理解了。另外,既然foreach不适合处理数组写操作,那么我们可以得出一个结 论,多数情况下,类似foreach ($array as $key => $value)形式的做数组写操作得代码都应该被替换成while (list($key) = each($array))。这些技巧产生的速度差异在小项目里可能并不明显,但是在类似框架这样的大项目中,一次请求动辄便会涉及到几 百几千几万次数组循环操作,差异就会明显放大。

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn