Fast code (100ms):
// Mixed could theoretically be an object or an array.
// In this example it's an array.
$mixed = array();
for($i = 0; $i < 10000; $i++) {
if (is_array($mixed)) {
$mixed[getRandomStr(15)] = 'abcd';
} else {
// Do something else which we don't care about here
}
}
Terribly slow code (4000ms): (note that $mixed is passed by reference)
function put(&$mixed, $key, $value) {
if (is_array($mixed)) {
$mixed[$key] = $value;
} else {
// Do something else which we don't care about here
}
}
$mixed = array();
for($i = 0; $i < 10000; $i++) {
put($mixed, getRandomStr(15), 'abcd');
}
Now it's fast again: (note that the is_array check has been dropped here)
function put(&$mixed, $key, $value) {
$mixed[$key] = $value;
}
$mixed = array();
for($i = 0; $i < 10000; $i++) {
put($mixed, getRandomStr(15), 'abcd');
}
Now we wrap the array inside an object and reintroduce the is_array check ... and it's still fast:
function put($objWrap, $key, $value) {
if (is_array($objWrap->mixed)) {
$objWrap->mixed[$key] = $value;
} else {
// Do something else which we don't care about here
}
}
$objWrap = new stdClass;
$objWrap->mixed = array();
for($i = 0; $i < 10000; $i++) {
put($objWrap, getRandomStr(15), 'abcd');
}
This happens with PHP 5.3 and 5.4.
Does anyone know why? (and/or how to work around this problem)
My guess: passing a reference to the array to is_array() causes the whole array to be copied, slowing the process down.
Note: you can replace is_array() with !is_object() or even with gettype() === 'array'. It does not change a bit.