zoukankan      html  css  js  c++  java
  • 深思 PHP 数组遍历的差异(array_diff 的实现)

    function array_diff($array_1, $array_2) { 
        $diff = array(); 
    
        foreach ($array_1 as $k => $v1) { 
            $flag = false; 
            foreach ($array_2 as $v2) { 
                if ($flag = ($v1 == $v2)) { 
                    break; 
                } 
            } 
    
            if (!$flag) { 
                $diff[$k] = $v1; 
            } 
        } 
    
        return $diff; 
    }
    

      

    虽然实现是可以的,但是发现这个函数的效率是惨不忍睹。于是我又重新考虑了下,并优化了算法,第二个函数看起来是这个样子的: 

    function array_diff($array_1, $array_2) { 
        foreach ($array_1 as $key => $item) { 
            if (in_array($item, $array_2, true)) { 
                unset($array_1[$key]); 
            } 
        } 
    
        return $array_1; 
    }
    

      


    嗯,这次几乎可以和原 array_diff 函数的速度媲美了。但是还有没有更优化的办法呢?由 ChinaUnix 上的一篇文章(不好意思,作弊了),我发现 PHP 竟然可以这样写: 

    function array_diff($array_1, $array_2) { 
        $array_2 = array_flip($array_2); 
        foreach ($array_1 as $key => $item) { 
            if (isset($array_2[$item])) { 
                unset($array_1[$key]); 
            } 
         } 
    
        return $array_1; 
    }
    

      


    这个函数的效率非常的惊人,甚至比原 array_diff 函数的速度都要快。究其原因,我找到了解释: 

    因为键是进行 HASH 组织的,查找很快; 
    而 Value 只是由 Key 组织存放,本身没有索引,每次查找都是遍历。总结 
    这虽然是 PHP 语言的一个小窍门,但在遍历和对比数组的值上,如果需要对比值将其与键反转的确比通常的值对值的比较效率要高得多。 

    比如,上面的函数二需要调用 in_array 函数需要循环判断是否在函数内;而函数三则仅仅判断这个数组是否存在该键就可以了。加上数组键和值不同的组织索引方式,效率比想象的还高那就非常可以理解了。 

    附代码

    复制代码代码如下:
    <?php 
    function microtime_float() { 
        list($usec, $sec) = explode(" ", microtime()); 
        return ((float)$usec + (float)$sec); 
    } 
    
    function array_diff2($array_1, $array_2) { 
        $diff = array(); 
    
        foreach ($array_1 as $k => $v1) { 
            $flag = false; 
            foreach ($array_2 as $v2) { 
                if ($flag = ($v1 == $v2)) { 
                    break; 
                } 
            } 
    
            if (!$flag) { 
                $diff[$k] = $v1; 
            } 
        } 
    
        return $diff; 
    } 
    
    
    function array_diff3($array_1, $array_2) { 
        foreach ($array_1 as $key => $item) { 
            if (in_array($item, $array_2, true)) { 
                unset($array_1[$key]); 
            } 
        } 
    
        return $array_1; 
    } 
    
    
    function array_diff4($array_1, $array_2) { 
        $array_2 = array_flip($array_2); 
        foreach ($array_1 as $key => $item) { 
            if (isset($array_2[$item])) { 
                unset($array_1[$key]); 
            } 
         } 
    
        return $array_1; 
    } 
    
    ////////////////////////////// 
    
    for($i = 0, $ary_1 = array(); $i < 5000; $i++) { 
        $ary_1[] = rand(100, 999); 
    } 
    
    for($i = 0, $ary_2 = array(); $i < 5000; $i++) { 
        $ary_2[] = rand(100, 999); 
    } 
    
    header("Content-type: text/plain;charset=utf-8"); 
    
    $time_start = microtime_float(); 
    array_diff($ary_1, $ary_2); 
    echo "函数 array_diff 运行" . (microtime_float() - $time_start) . " 秒
    "; 
    
    $time_start = microtime_float(); 
    array_diff2($ary_1, $ary_2); 
    echo "函数 array_diff2 运行" . (microtime_float() - $time_start) . " 秒
    "; 
    
    $time_start = microtime_float(); 
    array_diff3($ary_1, $ary_2); 
    echo "函数 array_diff3 运行" . (microtime_float() - $time_start) . " 秒
    "; 
    
    $time_start = microtime_float(); 
    array_diff4($ary_1, $ary_2); 
    echo "函数 array_diff4 运行" . (microtime_float() - $time_start) . " 秒
    "; 
    ?> 
    

      

     
     
    例子 1
    <?php
    $my_array = array("Dog","Cat","Horse");
    
    list($a, $b, $c) = $my_array;
    echo "I have several animals, a $a, a $b and a $c.";
    ?>
    输出:
    I have several animals, a Dog, a Cat and a Horse.
    

      

    例子
    <?php
    echo(microtime());
    ?>
    输出:
    0.25139300 1138197510
    

      

    //break是结束整个循环体,continue是结束单次循环
    
    比方说:
    
    while(x++ < 10)
    {
        if(x == 3)
        {
            break;
        }
        printf("%d
    ", x);
    }
    结果是输出  1 2   就退出了整个while循环
    
    但是如果使用continue
    while(x++ < 10)
    {
        if(x == 3)
        {
            continue;
        }
        printf("%d
    ", x);
    }
    结果是:1 2 4 5 6 7 8 9 10  可见他仅仅是不输出3,因为他结束了本次循环
    

      

  • 相关阅读:
    Web 请求响应原理(转)
    openstack中的floating ip与阿里云的公网ip
    一起来说 Vim 语
    vsftpd.conf 详解与实例配置
    jquery 放大图片
    jQuery 之 .stop() 方法
    jquery 插件开发
    jquery 之效果
    jquery 之事件 多库共存(noConflict)
    测试网站是共享还是独立ip
  • 原文地址:https://www.cnblogs.com/fengzhiqiangcaisangzi/p/3449422.html
Copyright © 2011-2022 走看看