Dai Chong's blog

一、前言

 对于任何计算机程序,程序的运行性能决定了一个程序的好坏,夸张一点说程序性能的好坏直接影响了一个互联网公司的生存与发展的问题。所以对于程序员,优化性能的技能是必不可少的,就因为不会优化性能,可能就会比其他人差好几个等级。

 在PHP界,大部分互联网公司的工作内容就是最常见的CURD。你会发现自己和一些应届毕业生相比完全没有竞争优势,甚至一些公司的岗位要求也只是会CURD就行了。就像我最近找工作,不止一次的遇到面试官问:“我你觉得你的优势是什么?”,我每次都是哑口无言。

 大家都懂为了避免这样的出现,学了很多种语言。造成现在PHP岗位的要求从只会PHP语言到PHP+MYSQL+LIUNX+HTNL+CSS+JS,甚至我对面试官说:“我的优势是比其他人会的语言多!”的时候,他会回你一句:“这不是大家都会的吗?”。

 更恐怖的是,现在的PH招聘要求上都TM开始写要求熟悉JAVA、Python、Go、Golang,你TM能再过分点吗?

二、言归正传

 在PHP中最常见的就是foreach,处理数据交际的时候一般第一时间想到的都是嵌套。

 在这我只能说尽量少用或者不使用这样的写法。

 下面介绍3种可以代替循环嵌套写法例子,并分析执行的效率和性能问题。

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<?php

ini_set('memory_limit','3072M');

$arr = [];
$arr1 = [];

for($i=1;$i<=1000000;$i++){
$arr[$i] = [
'id' => ($i+1)*2,
'name' => '戴崇_'.$i
];
}

for($j=1;$j<=1000000;$j++){
$arr1[$j] = [
'uid' =>($j+1)*2,
'age' => $j
];
}


$t1 = microtime(true);

$mode = mode1($arr,$arr1);

echo '<br />';
$t2 = microtime(true);
echo $mode . '耗时: '.round($t2-$t1,3).' 秒<br />';
echo '内存消耗: ' . memory_get_usage() / 1024 / 1024 . ' MB<br />';

// 循环嵌套
function mode($arr,$arr1){

foreach ($arr as $k => $v) {
foreach ($arr1 as $key => $value) {
if($v['id'] == $value['uid']){
$arr[$k]['age'] = $value['age'];
}
}
}

return '方法一->循环嵌套法->';
}

// 循环拆分
function mode1($arr,$arr1){
$arr1 = array_index($arr1,'uid');

foreach ($arr as &$value) {
if(isset($arr1[$value['id']])){
$value['age'] = $arr1[$value['id']]['age'];
}
}

return '方法二->循环拆分->';
}

// array_walk 闭包
function mode2($arr,$arr1){

$arr1 = array_index($arr1,'uid');

array_walk($arr, function(&$value,$key) use ($arr1) {
if(isset($arr1[$value['id']])){
$value['age'] = $arr1[$value['id']]['age'];
}

});

return '方法二->array_walk 闭包->';
}

// array_map

function mode3($arr,$arr1){

$arr1 = array_index($arr1,'uid');

$arr = array_map(function(&$value) use ($arr1) {
if(isset($arr1[$value['id']])){
$value['age'] = $arr1[$value['id']]['age'];
}
return $value;
}, $arr);

return '方法三->array_map->';
}

// 把多维数组中的某个键值设置为键名
function array_index(array $array, $name)
{
$indexedArray = array();
if (empty($array)) {
return $indexedArray;
}
foreach ($array as $item) {
if (isset($item[$name])) {
$indexedArray[$item[$name]] = $item;
continue;
}
}
return $indexedArray;
}

 经过试验的到结果:

  (1)方法一:10000*10000(万级) 执行时间 3.377 秒

  (2)方法二:1000000*1000000(百万级) 执行时间: 0.741 秒 0.642 秒 0.673 秒 0.609 秒 0.618 秒

  (3)方法三:1000000*1000000(百万级) 执行时间: 0.745 秒 0.75 秒 0.664 秒 0.672 秒 0.684 秒

  (4)方法四:1000000*1000000(百万级) 执行时间: 0.781 秒 0.803 秒 0.661 秒 0.661 秒 0.658 秒

三、总结

 在开发中一定要考虑数据量大的情况下会出现的问题,尽量使用上面的方法代替循环嵌套。另外还要注意代码风格和规范等问题。

 希望大家在看了之后能有所收获。


 评论