tags:

views:

46

answers:

2

Hi, I wonder what is the speed price of using inheritance in php.

+1  A: 

I think you don't have to care about speed in this case , even if you have to extend in 1000 classes.

Centurion
I would agree If we was not able to use is_subclass_of or # get_class() or get_parent_class() or is_a(). these functions should look up some where to extract related information. The creation of such a table is a cost.
Erkin Tek
@Erkin Yes, but the overhead is absolutely insignificant. If you have a need for micro optimization at that level, PHP is the wrong language for you.
deceze
@Erkin Tek, maybe, but who will extend 1000 classes tree, but for a few classes is insignificant.
Centurion
+2  A: 

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 ;)

Gordon
thank you for your answer,
Erkin Tek