0

配列を指定された回数回転させてから最初のインデックスを返すことができる関数を作成しようとしています。しかし、私が持っているのは本当に遅くて不格好です。見てみましょう:

<?php

/**
 * Get the current userid
 * @return integer
 */
public function getCurrentUser( DateTime $startDate, DateInterval $interval, DateTime $endDate, $currentUser, $users, $rotating )
{

    if ($rotating == 0)
    {
        return $currentUser;
    }

    $usrArray = array();
    $dateRange = new DatePeriod( $startDate, $interval, $endDate);

    // Push userIds to an array
    foreach ($users as $user)
    {
        $usrArray[] = $user->id;
    }

    // Get the number of iterations from startDate to endDate
    $steps = iterator_count($dateRange);

    // Find the initial position of the orignal user
    $key = array_search($currentUser, $usrArray);

    // Set up the array so index 0 == currentUser
    $usr = $usrArray;
    array_splice($usr, $key);
    $slice = array_slice($usrArray, $key);
    $startList = array_merge($slice, $usr);

    // Start rotating the array
    for ($i=0; $i < $steps; $i++)
    {
        array_push($startList, array_shift($startList));
    }

    return $startList[0];
}

PHP スクリプトがタイムアウトする前の Xdebug プロファイルを次に示します。 xdebug プロファイル

x 回の回転後にインデックス 0 を特定するより良い方法はありますか?

4

1 に答える 1

0

アレイのローテーションはそれほど遅くはありませんが、改善することができます..これがローテーションコードだと思います

あなたのコード

// Start rotating the array
for ($i=0; $i < $steps; $i++)
{
    array_push($startList, array_shift($startList));
}

return $startList[0];

ループを削除してmodに置き換えることができます..ここで同じ結果を得る方法は次のとおりです。

解決

return $startList[ $steps % count($startList)];

同じ結果が得られます。

シンプルなベンチマークとテスト

$steps = 10000; <----------------- 10,000 steps 

set_time_limit(0);
echo "<pre>";
$file = "log.txt";
// Using your current code
function m1($steps) {
    $startList = range("A", "H");
    for($i = 0; $i < $steps; $i ++) {
        array_push($startList, array_shift($startList));
    }
    return $startList[0];
}

// Using InfiniteIterator
function m2($steps) {
    $startList = range("A", "H");
    $n = 0;
    foreach ( new InfiniteIterator(new ArrayIterator($startList)) as $l ) {
        if ($n == $steps) {
            return $l;
            break;
        }
        $n ++;
    }
}

// Simple MOD solution
function m3($steps) {
    $startList = range("A", "H");
    return $startList[ $steps % count($startList)];
}

$result = array('m1' => 0,'m2' => 0,'m3' => 0);

for($i = 0; $i < 1; ++ $i) {
    foreach ( array_keys($result) as $key ) {
        $alpha = microtime(true);
        $key($file);
        $result[$key] += microtime(true) - $alpha;
    }
}

echo '<pre>';
echo "Single Run\n";
print_r($result);
var_dump(m1($steps),m2($steps),m2($steps));
echo '</pre>';

出力

Single Run
Array
(
    [m1] => 0.00012588500976562
    [m2] => 0.00021791458129883
    [m3] => 7.7962875366211E-5   <----------------- Mod solution fastest 
)
string 'A' (length=1)               |
string 'A' (length=1)               |+------------- They all return same result
string 'A' (length=1)               |
于 2012-11-24T09:16:41.127 に答える