PHP数组的一些实用技巧与建议
使用连续整数填充数组
range($start, $end, $step = 1)
使用连续整数填充一个数组,可以通过修改$step
改变填充间隔
删除多个连续元素
array_splice($array, $offset, $length)
判断元素是否存在于数组中
in_array($search, $arr, true);
当查找的数据量较少时候,使用in_array
,当数据量较大时,使用array_filp()
将数组键值对反转,通过isset
结构判断,有更好的性能,使用in_arry
是线性时间,而关联数组是常量时间
$search = [];
// 数据量
for ($n = 1000; $n >= 1; $n--) {
$search[] = random_int(1, 999999);
}
$list = range(1, 9999999, 1);
$start = microtime(true);
foreach ($search as $v) {
in_array($v, $list, true);
}
echo "in_array 耗时 " . (microtime(true) - $start) . 's' . PHP_EOL;
$start = microtime(true);
$list = array_flip($list);
foreach ($search as $v) {
if (isset($list[$v])) {
}
}
echo "isset 耗时 " . (microtime(true) - $start) . 's' . PHP_EOL;
array_filter 性能远不如 foreach循环判断
一般来说,php内置函数性能要优于用户代码,很少情况不是,array_filter()
就属于比较特殊的,建议,如果是数据量较大的操作,能用array_filter
和foreach
完成,优先选用foreach
$res = [];
$list = range(1, 1000000, 1);
$start = microtime(true);
foreach ($list as $v) {
if (0 === $v % 9765) {
$res[] = $v;
}
}
echo "foreach 耗时 " . (microtime(true) - $start) . 's' . PHP_EOL;
$start = microtime(true);
$res = array_filter($list, function ($v) {
return 0 === $v % 9765;
});
echo "array_filter 耗时 " . (microtime(true) - $start) . 's' . PHP_EOL;
不要使用引用循环
实际上,引用循环的速度可能比普通循环还要慢,其次,如果引用循环使用以后,未及时释放变量,会导致一些意外的结果
$a1 = [1, 2, 3];
$b1 = [4, 5, 6];
foreach ($a1 as &$v) {}
// unset($v); // 这里需要释放引用使用的变量
foreach ($b1 as $v) {}
print_r($a1);
print_r($b1);
usort()
函数的替代函数 array_sort()
缓存比较值,排序元素超过10个时候,array_sort
速度会更快
function array_sort(array $array, callable $callback, string $sort = 'asc'): array
{
$mapped = array_map($callback, $array);
if ('asc' === $sort) {
asort($mapped);
} else {
arsort($mapped);
}
$res = [];
foreach ($mapped as $k => $v) {
$res[] = $array[$k];
}
return $res;
}
// 以字符串长度排序
$a = ['xxxx', 'a', 'b', 'abcdec', '342usfd'];
$arr = array_sort($a, static function ($item) {
return mb_strlen($item);
});
print_r($arr);
通过生成器读取大文件
function file_reader(string $file) {
if (!is_file($file)) {
throw new UnexpectedValueException('not a file');
}
$fp = fopen($file, 'rb');
while (false !== ($line = fgets($fp))) {
yield $line;
}
fclose($fp);
}
$f = file_reader(__FILE__);
foreach ($f as $k => $v) {
print_r($v);
}