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

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_map 呼び出しの代わりに array_column を使用できます。)

于 2013-06-17T02:33:57.487 に答える
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 に答える