It is because your function using the extended array object is not setting $z['aaa'] 2000 times but your function using ArrayObject is.
if i add a version of the extended array object function which does set $z['aaa'] the result is more consistant:
profiling(function()
{
global $times;
for ($i=0; $i<$times; $i++) {
$z = new MyArray();
for ($j=0; $j<$times; $j++) {
$z['bbb'] = 'bbb';
$z['ccc'] = $z['aaa'].$z['bbb'];
}
}
}, 'use extends arrayobject (no aaa)');
/* added MyArray function with $z['aaa'] = 'aaa' added to the loop */
profiling(function()
{
global $times;
for ($i=0; $i<$times; $i++) {
$z = new MyArray();
for ($j=0; $j<$times; $j++) {
$z['aaa'] = 'aaa';
$z['bbb'] = 'bbb';
$z['ccc'] = $z['aaa'].$z['bbb'];
}
}
}, 'use extends arrayobject (with aaa)');
output is as follows:
use array: 1.3838648796082
use object: 1.9023339748383
use arrayobject: 2.0339980125427
use extends arrayobject (no aaa): 1.6399688720703
use extends arrayobject (with aaa): 2.040415763855
phpversion 5.4.4-14+deb7u7
notice that the function using ArrayObject and the function using the extended ArrayObject with $z['aaa'] in the loop have much closer times.