昨天别人问了我一个问题,瞬间把我给问懵了。事情是这样的,问我给到一个既定数组,现在让我实现下将数组元素从低到高升序排列。第一个反应是直接使用ksort之类排序函数操作(一时脑子浆糊,这系列函数每次都要翻手册,实际上是asort)。告诉我,不能使用内置函数,需要自己写一个。好吧,这么大的坑,有简单的不用,要来个复杂的。当时写了个简单实现的方案,没多想,晚上闲着没事就想了下效率问题。最近对程序运行效率始终保持敏感。就想测试下各方法效率到底相差多少。
首先需要一个测试的数组,给定100W元素的数组。
第一问题就来了,如何快速有效的生成包含100W元素的无序数组?
其实当时我是想生成一个值为1-100W之间的随机数的。又脑子浆糊没想到啥简单办法,就将就使用下不重复的数据吧,不影响后续进行排序操作。简单办法:
$arr=range(1,1000000,1); shuffle($arr);
生成了既定数组后,就是排序操作了,这里应用下ThinkPHP5的debug函数,计算下脚本时间。
debug('begin'); asort($arr); debug('end'); dump(debug('begin','end').'s');
输出结果:string(9) "0.711041s"。耗时0.7秒完成了百万数据的排序操作,asort在PHP7的效率还是非常高的。
debug('begin'); $length=count($arr); for($i=0; $i<$length-1; $i++){ for($j=$i+1; $j $arr[$j]){ $temp = $arr[$i]; $arr[$i] = $arr[$j]; $arr[$j] = $temp; } } } debug('end'); dump(debug('begin','end').'s');
for的效率还真是底下,两层for就干脆别提了,意料之中的脚本超时,于是将既定数组缩小的1W。再次运行脚本,输出结果:string(9) "7.845449s"。1W数据竟然高达7秒。
$length=count($arr); $temp =0; for($i=0;$i<$length;$i++){ for($j=0;$j$arr[$j+1]){ $temp=$arr[$j]; $arr[$j]=$arr[$j+1]; $arr[$j+1]=$temp; } } }
运行结果:string(9) "9.343535s"。没想到冒泡竟然也如此低下。但凡两层for的都太低效了。印象中冒泡不能这么低啊,网上搜了下关于冒泡的改进方法。
$length = count($arr); $flag = TRUE; for($i = 0;($i < $length - 1) && $flag;$i ++){ $flag = FALSE; for($j = $length - 2;$j >= $i;$j --){ if($arr[$j] > $arr[$j + 1]){ $temp=$arr[$j]; $arr[$j]=$arr[$j+1]; $arr[$j+1]=$temp; $flag = TRUE; } } }
输出结果:string(9) "8.566490s"。比直接冒泡的提高了不到1秒。
通过简单测试看来还是通过PHP底层运算来的高效和简便。在不能使用内置函数的时候,如果基础知识不稳固,还是蛮吃力的。