At 06:23 31.05.2003, Evan Nemerson said:
--------------------[snip]--------------------
>IMHO the function()[] syntax should be allowed, but it isn't.
>
>You could use list() or extract(), but then you'd wind up with a lot more
>date 
>than you want. What I've been doing is creating a function, then calling when 
>needed. For example:
>
>function array_get_value($array, $index) {
>       return $array[$index];
>}
>
>array_get_value(getdate($timestamp), 'year');
--------------------[snip]-------------------- 

A little profiling notice on this here.

Constructing 3 testbeds, accessing an array through a function passing an
array reference (so the array won't get copied to the function), one using
your array_get_value() from above (without references, so the array will
get copied), and one using a local variable and direct access. 

The testbed source is copied below, as always. 
The numbers:

1.355221 secs (0.013552 msecs each): Copy local, direct access (100000 passes)
0.550718 secs (0.005507 msecs each): Ref local, direct access (100000 passes)
2.497536 secs (0.024975 msecs each): array_get_value (100000 passes)
0.906490 secs (0.009065 msecs each): array_get_value_ref (100000 passes) 

The interesting stuff is that storing the array to a local variable and
accessing it directly is slower than calling a function passing a reference
to the array. As you may notice, using array references is _always_ faster
by some factor, as copying the array is avoided.

Conclusion: use array references wherever you can. If you build a function
returning an array, let it return a reference (function &myfunc()), and use
this reference when calling ($var =& myfunc()). If you have this in a loop
it might save your script some valuable time.

Notes to the test scenario:
Since I've been interested in timing array access, not array creation, I've
used a static copy of the getdate() array, avoiding to profile the
getdate(time()) function.

// the static array to run the test with
$atime = getdate(time());

// return a reference to the array
function &arviaref() {
        global $atime;
        return $atime;
}

// return a copy of the array
function &arviacopy() {
        global $atime;
        return $atime;
}

//////////////////////////////////////////////////
// PROFILE CANDIDATES
function array_get_value_ref(&$array, $index) {
        return $array[$index];
}

function array_get_value($array, $index) {
        return $array[$index];
}
//////////////////////////////////////////////////

$LOOPS = 100000;

$x = measure();
for ($i = 0; $i < $LOOPS; ++$i) {
        $temp = arviacopy();
        $rslt = $temp['year'];
}
echo measure($x, 'Copy local, direct access (%1$d passes)', $i, array($i));

$x = measure();
for ($i = 0; $i < $LOOPS; ++$i) {
        $temp =& arviaref();
        $rslt = $temp['year'];
}
echo measure($x, 'Ref local, direct access (%1$d passes)', $i, array($i));

$x = measure();
for ($i = 0; $i < $LOOPS; ++$i)
        $rslt = array_get_value(arviaref(), 'year');
echo measure($x, 'array_get_value (%1$d passes)', $i, array($i));

$x = measure();
for ($i = 0; $i < $LOOPS; ++$i)
        $rslt = array_get_value_ref(arviaref(), 'year');
echo measure($x, 'array_get_value_ref (%1$d passes)', $i, array($i));

function measure($start = null, $string = null, $passes = null, $params = null)
{
        // the bias is the effort made for calling measure() twice
        // and constructing the optional array parameter for the second call
        // note we do not run measure($start, $string, $passes, $params) since
        // this would add a lot of action that gets not timed by measure()
        // to the bias value.
        static $bias = -1;
        if ($bias == -1) {
                $bias = 0;
                $x = microtime();
                for ($i = 0; $i < 1000; ++$i) {
                        measure(); measure();
                        $a = array('string entry','string entry','string
entry');
                }
                $y = microtime();
                list($s0, $s1) = explode(' ', $x);
                list($e0, $e1) = explode(' ', $y);
                $bias = (($e0 + $e1) - ($s0 + $s1)) / 1000;
        }

        // get the current time
        $x = microtime();

        // if the start time is set, this is a final profiling call
        if ($start) {
                list($s0, $s1) = explode(' ', $start);
                list($e0, $e1) = explode(' ', $x);
                $time = ($e0 + $e1) - ($s0 + $s1) - $bias;
                if (is_array($params)) {
                        $cmd = "return sprintf(\$string, '" . join("','",
$params) . "');";
                        $string = eval($cmd);
                }
                if ($passes)
                        $x = sprintf("%f secs (%f msecs each): %s\n",
$time, ($time * 1000) / $passes, $string);
                else
                        $x = sprintf("%f secs: %s\n", $time, $string);
        }

        // return either the time, or the profiling string
        return $x;
}



-- 
   >O     Ernest E. Vogelsinger
   (\)    ICQ #13394035
    ^     http://www.vogelsinger.at/



-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to