Hi, I wonder what is the speed price of using inheritance in php.
I think you don't have to care about speed in this case , even if you have to extend in 1000 classes.
Inheritance is a key element of OOP. You should not concern yourself about any speed impact it might have. You can (and should) favor composition and aggregation over inheritance, but if your design needs inheritance, you use it. Anything else would be like saying you wanna play baseball without a bat. Inheritance is part of the game.
Anyway, here is a little something to run with your favorite profiler:
<?php error_reporting(-1); ini_set('memory_limit', '1024M');
// Create classes A to Z with each class extending the previous class
class A { public function fn() { return TRUE; } }
$previous = 'A';
foreach(range('B','Z') as $klass) {
eval(sprintf('class %s extends %s{}', $klass, $previous));
$previous = $klass;
}
// create results for non-inheriting class A
function A_is_a() { return is_a(new A, 'A'); }
function A_get_class() { return get_class(new A); }
function A_get_parent() { return get_parent_class(new A); }
function A_call_fn() { $a = new A; return $a->fn(); }
// create results for Z that inherits from Y ... that inherits from A
function Z_is_a() { return is_a(new Z, 'A'); }
function Z_get_class() { return get_class(new Z); }
function Z_get_parent() { return get_parent_class(new Z); }
function Z_call_fn() { $z = new Z; return $z->fn(); }
for($i=0;$i<10000;$i++) A_is_a();
for($i=0;$i<10000;$i++) A_get_class();
for($i=0;$i<10000;$i++) A_get_parent();
for($i=0;$i<10000;$i++) A_call_fn();
for($i=0;$i<10000;$i++) Z_is_a();
for($i=0;$i<10000;$i++) Z_get_class();
for($i=0;$i<10000;$i++) Z_get_parent();
for($i=0;$i<10000;$i++) Z_call_fn();
Results on my machine using PHP5.3.3 CLI and Zend Debugger
Function Calls Av. Own Own Time Others Total
A_is_a 10000 0,000003 0,025626 0,000000 0,025626
A_get_class 10000 0,000002 0,022033 0,000000 0,022033
A_get_parent 10000 0,000002 0,020804 0,000000 0,020804
A_call_fn 10000 0,000003 0,034949 0,012274 0,047223
Z_is_a 10000 0,000002 0,024436 0,000000 0,024436
Z_get_class 10000 0,000003 0,028833 0,000000 0,028833
Z_get_parent 10000 0,000002 0,022144 0,000000 0,022144
Z_call_fn 10000 0,000003 0,033359 0,012549 0,045908
Disclaimer: Note that results may vary on your machine and also note that isolated benchmarks are usually pointless anyway, especially when it is about µ-optimizations like this. You could change the code to extend 1000 classes and then you will see a difference in the is_a
function call, but seriously, if any of your productive code extends 1000 classes you got bigger problems ;)