for和foreach那个效率更高?原因是什么?

本文探讨了PHP编程中for循环和foreach循环的效率差异,通过测试代码展示了两者耗时,得出foreach在大多数情况下效率更高的结论。尽管如此,作者认为在实际开发中,由于foreach的便利性,通常推荐使用它,而for循环的存在可能有其特定场景的适用性。

成功不是将来才有的,而是从决定去做的那一刻起,持续累积而成。


这里写图片描述


写这篇文章的原因主要是在开发过程中突然有以下几个疑问,特抽出时间深度探究一下,以加深自身对php的理解。

1、作为一名phper,for和foreach循环遍历几乎每天都在使用,那么这两种遍历方式哪一种效率更高呢?
2、效率高的原因是什么呢?
3、原理分别是什么呢?

首先要解决第一个问题,我们可以通过一个简单的测试看一下测试结果,测试代码如下:

for循环遍历方法:

public function getForTime(){
    $big_Array = range(0,1000000,1);

     /* for循环遍历数组示例 */
    $start_For_Time = $this->microtime_float();
    //$array_Count = count($big_Array);
    for ($i=0;$i<count($big_Array);$i++) {
            $i;
    }
    $end_For_Time = $this->microtime_float();
    $for_Time = $end_For_Time - $start_For_Time;
    echo 'for循环遍历耗时:'.$for_Time.'<br>';
}

foreach循环遍历方法:

public function getForeachTime(){
$big_Array = range(0,1000000,1);

 /* foreach循环遍历数组示例 */
    $start_Foreach_Time = $this->microtime_float();
    foreach ($big_Array as $key=>$val) {
            $key;
    }
    $end_Foreach_Time = $this->microtime_float();
    $foreach_Time = $end_Foreach_Time - $start_Foreach_Time;
    echo 'foreach循环遍历耗时:'.$foreach_Time;
}

时间计算方法:

/**
 *  时间统计函数
 */
private function microtime_float($time = null)
{
   list($usec, $sec) = explode(' ', $time ? $time : microtime());
   return ((float)$usec + (float)$sec);
}

看一下两种方式耗时

/*
 * 输出结果:第一种情况:先count在for循环遍历耗时:0.028002023696899 秒
 *                         foreach循环遍历耗时:0.003000020980835 秒
 *        第二种情况:在for循环条件中做count遍历耗时:0.095005035400391 秒
 *                            foreach循环遍历耗时:0.0040009021759033 秒
 * */

从上面的测试中我们可以明显的得出两条结论:

1、for循环遍历的效率是低于foreach循环遍历
2、for循环在外部做count和在条件中做count相比较,第一种效率更高

那么第二个问题:效率高的原因是什么呢?在寻找这个答案之前我们先探讨第三个问题,我们看一下原理分别是什么。

for 循环:

每次从$i开始,每次循环都需要判断$i是否小于count,这占用了很大一部分时间
小于继续,否则终止循环

foreach:

foreach 依赖 IEnumerable.

第一次 var a in GetList() 时 调用 GetEnumerator 返回第一个对象 并 赋给a,

以后每次再执行 var a in GetList() 的时候 调用 MoveNext.直到循环结束.

期间GetList()方法只执行一次.

从上面是分析我们明显可以得出结论:php 的foreach循环效率是大大高于for循环。

BUT:事实真的是这样吗?有人会说这个例子已经很明显了啊,结论一目了然,难道还有其他的可能吗?

我觉得事实没这么简单,如果真的是这样,for循环存在的意义是什么呢?

既然foreach效率高于for这么多倍,就直接都用foreach不就行了吗?个人觉得我测试的这个例子有一定的局限性,并不能作为评估两个循环方式效率高低的绝对依据。

不过,对于我们phper来说,正常工作当中还是使用foreach循环遍历比较好,至于编译层是如何工作的没必要涉及太深,如果有兴趣可以深度研究一下。

### 性能对比分析 在评估 MyBatis 中批量插入操作 `batch` 方法与使用 `IN` 关键字的方法时,主要关注点在于执行效率、资源消耗以及数据库交互次数。 #### Batch 插入方式 Batch 方式通过设置 `useGeneratedKeys="true"` `keyProperty="id"` 可以实现自增主键的获取[^1]。这种方式允许应用程序一次性提交多条记录到数据库服务器,减少了客户端与服务端之间的通信开销。对于大量数据的操作来说,这通常会带来更好的性能表现: ```sql INSERT INTO table_name (column_list) VALUES (...),(...),(...) ``` #### 使用 IN 关键字的方式 当采用 `IN` 来处理多个值的情况下,SQL 查询语句会被构造成如下形式: ```sql SELECT * FROM table WHERE id IN (?, ?, ? ...) ``` 这种情况下,虽然可以减少 SQL 语句的数量,但是每一条 SELECT 或者 INSERT 的参数列表可能会变得非常庞大,从而影响解析速度并增加内存占用。更重要的是,这种方法并不适用于所有的场景特别是涉及到大批量的数据写入操作时。 #### 实际测试案例 为了更直观地理解两者间的差异,可以通过编写简单的 Java 测试程序来模拟不同规模下的插入操作,并测量其耗时情况。下面是一个基于 JUnit 的简单例子用于展示如何进行这样的基准测试(注意实际环境中还需要考虑更多因素如网络延迟等): ```java @Test public void testPerformance() { int batchSize = 1000; // 准备数据... long startTime = System.currentTimeMillis(); sqlSession.batch().execute(new Runnable(){ @Override public void run(){ try{ for(int i=0; i<totalRecordsCount / batchSize ;i++){ List<Object> recordsToInsertInThisBatch = getBatchData(i*batchSize, batchSize); insertIntoDatabase(recordsToInsertInThisBatch); // 这里调用了带有 foreach 循环配置的 mapper 接口 } }finally{session.commit();} } }); long endTime = System.currentTimeMillis(); System.out.println("Batch Insert Time Cost:"+(endTime-startTime)); } ``` 上述代码片段展示了利用 MyBatis 提供的批处理功能来进行高效的大规模数据加载过程中的时间成本计算方法。
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值