1

我有以下代码需要很长时间才能执行。有时它甚至超时。

foreach ($totalownerships as $totalownership) {
    if (!in_array($totalownership['titleno'], $totaltitles)) {
        $result['totalowns'] += 1;
        $totaltitles[] = $totalownership['titleno'];
        $result['ownershipid'] = $result['ownershipid'] . " " .$totalownership['titleno'];
    }
}

$totalownerships数组大小52225为。有没有更好的方法来编写这段代码,这样它就不需要很长时间来执行?

4

2 回答 2

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

于 2013-06-17T02:24:54.347 回答
2

O(n)我不会使用 in_array 操作,而是使用O(1)keylook up:

$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 调用。)

于 2013-06-17T02:33:57.487 回答