我是PHP的新手,需要一个关于数组搜索的建议。
如果我想在多维数组中搜索一个元素,我可以使用array_filter
,也可以循环遍历数组,看看是否存在符合我的条件的元素。
我在很多地方看到这两种建议。哪个更快?下面是一个示例数组:
Array (
[0] => Array (
[id] => 4e288306a74848.46724799
[question] => Which city is capital of New York?
[answers] => Array (
[0] => Array (
[id] => 4e288b637072c6.27436568
[answer] => New York
[question_id_fk] => 4e288306a74848.46724799
[correct] => 0
)
[1] => Array (
[id] => 4e288b63709a24.35955656
[answer] => Albany
[question_id_fk] => 4e288306a74848.46724799
[correct] => 1
)
)
)
)
我正在这样搜索。
$thisQuestion = array_filter($pollQuestions, function($q) {
return questionId == $q["id"];
});
我知道这个问题很老,但是我不同意这个公认的答案。我也想知道,如果foreach()
循环和array_filter()
函数之间存在差异,并发现以下帖子:
Levi Jackson做了一个很好的工作,比较了几个循环和array_*()
函数的速度。根据他的说法,foreach()
循环比array_filter()
函数快。虽然它在很大程度上没有太大的区别,但当您必须处理大量数据时,它就开始起作用了。
我做了一个测试脚本,因为我有点怀疑…内部函数怎么可能比循环慢…
但实际上这是真的。另一个有趣的结果是php 7.4几乎比7.2快10倍!
你可以自己试试
<?php
/*** Results on my machine ***
php 7.2
array_filter: 2.5147440433502
foreach: 0.13733291625977
for i: 0.24090600013733
php 7.4
array_filter: 0.057109117507935
foreach: 0.021071910858154
for i: 0.027867078781128
php 8.2
array_filter: 0.069692134857178
foreach: 0.018320083618164
for i: 0.019519329071045
**/
ini_set('memory_limit', '500M');
$data = range(0, 1000000);
// ARRAY FILTER
$start = microtime(true);
$newData = array_filter($data, function ($item) {
return $item % 2;
});
$end = microtime(true);
echo "array_filter: ";
echo $end - $start . PHP_EOL;
// FOREACH
$start = microtime(true);
$newData = array();
foreach ($data as $item) {
if ($item % 2) {
$newData[] = $item;
}
}
$end = microtime(true);
echo "foreach: ";
echo $end - $start . PHP_EOL;
// FOR
$start = microtime(true);
$newData = array();
$numItems = count($data);
for ($i = 0; $i < $numItems; $i++) {
if ($data[$i] % 2) {
$newData[] = $data[$i];
}
}
$end = microtime(true);
echo "for i: ";
echo $end - $start . PHP_EOL;
我知道这是一个古老的问题,但我将给出我的两点意见:对我来说,使用foreach循环比使用array_filter要快得多。使用foreach,按id执行搜索需要1.4秒,使用过滤器需要8.6秒。
从我自己的经验来看,foreach
更快。我认为这与函数调用开销,参数检查,复制到变量返回指令等有关。当使用基本语法时,解析的代码更有可能接近编译/解释的字节码,对核心有更好的优化。
通常的规则是:任何东西都更简单,运行更快(意味着更少的检查,更少的功能,只要它有你需要的一切)
Array_Filter
遍历输入数组中的每个值,将它们传递给回调函数。如果回调函数返回true,则当前将输入的值返回到结果数组中。数组键是保留。