Benchmarking Extendable Object Faces

Submitted by fago on Mon, 07/06/2009 - 21:47
I've started with crell's results when benchmarking magic. I also used his code snipped to run 2.000.000 iterations. As for crell's results, only the relative comparison is from interest, not the absolute numbers. I benchmarked calling a single function or method, which just prefixes the name of the object, which is to be extended:
<?php
 
function faces_test_extension_function($object, $prefix) {
  return
$prefix . $object-
?>
name; } ?> I've done so, so that the results also take the time to access the object into account. I started with benchmarking a direct function or method call and compared it to call_user_func_array() and to using the reflection API to invoke a function or method. I benchmarked using the reflection API with and without the reflection object creation, e.g. this would be the whole method call using reflection:
<?php
 $method
= new ReflectionMethod('RulesTestExtender', 'isWorking2');
 
$method-
?>
invokeArgs($element, array('d')); ?> Thus one could instantiate the $method object once and reuse it multiple times. So I benchmarked the second call on its own too.
FunctionMethod
Direct call3,70s3.17s
Using call_user_func_array()7.21s7.82s
Using reflection11.05s13.09s
Using reflection, call only6.04s6.50s
As you can see the whole reflection call is slower then call_user_func_array(), however the method invocation call only is a bit faster. However to be able to reuse the $method objects multiple times one would have to keep them in memory all the time, requiring a more complicated logic and still - the first invocation would be slower. So I decided that all this trouble isn't worth it for being theoretically a tiny bit faster *if* a method is called very often, so I'm staying with call_user_func_array keeping single usage fast. Ok, so here are the results for using Extendable Object Faces:
Function ExtensionClass Extension
incorporated face16.36s16.68s
added face19.00s19.44s
added face, $face given16.45s16.75s
Update: Separate faces have been removed, the API performs as shown for incorporated faces. Compared to using call_user_func_array() directly the Object Faces are 2,2 to 2,6 times slower. I think this is an acceptable good performance - of course each abstraction makes things slower a little bit. Given the advantages they bring, I think it's very well worth it :).