我有以下代码需要花费很长时间才能执行。有时它甚至会超时。
foreach ($totalownerships as $totalownership) {
if (!in_array($totalownership['titleno'], $totaltitles)) {
$result['totalowns'] += 1;
$totaltitles[] = $totalownership['titleno'];
$result['ownershipid'] = $result['ownershipid'] . " " .$totalownership['titleno'];
}
}
$totalownerships
数组大小为52225
。是否有更好的方法来编写此代码,以便它不需要很长时间才能执行?
答案 0 :(得分:2)
这将快得多,使用PHP的快速内置数组操作工具来消除循环中的数组搜索:
// Add all titles to $totaltitles, for added speed
foreach ($totalownerships as $totalownership) {
$totaltitles[] = $totalownership['titleno'];
}
// For PHP 5.5+ you can use array_column() to get just the titleno field
//$totaltitles = array_column($totalownership, 'titleno');
// Use array_unique() to eliminate duplicate titles from $totaltitles
array_unique($totaltitles);
// Use count() to get a total count of $totaltitles
$result['totalowns'] = count($totaltitles);
// Use implode() for concatenation of title names
$result['ownershipid'] .= " " . implode(" ", $totaltitles);
有关更多PHP性能提示,请查看:PHP Bench
答案 1 :(得分:2)
我不会使用O(n)
in_array操作,而是使用O(1)
键查找:
$totaltitles = array();
foreach ($totalownerships as $totalownership) {
if (!isset($totaltitles[$totalownership['titleno']])) {
$totaltitles[$totalownership['titleno']] = $totalownership['titleno'];
$result['ownershipid'] .= " " . $totalownership['titleno'];
}
}
$result['totalowns'] = count($totaltitles);
基本上,我们的想法是将您的唯一属性用作数组键,这样您就可以使用常量时间查找而不是线性查找。
如果您想采取(可能更慢)更漂亮的路线,您可以尝试:
$uniques = array_unqiue(array_map(function($own) {
return $own['titleno'];
}, $totalownerships));
$result = array(
'ownershipid' => implode(' ', $uniques),
'totalowns' => count($uniques)
);
(正如Steven Moseley所说,如果您使用的是PHP 5.5,则可以使用array_column而不是该array_map调用。)