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