Page 1 of 1

Performance Implications of Requiring Many Class Definitions

Posted: Tue Jul 18, 2006 1:19 pm
by Ollie Saunders
Say you have some code that make use of a package (in the loose sense of the word). In order to use the package you require a single file:

Code: Select all

// contents of index.php
require_once 'SuperDupaPackage.php';
Which requires all the classes defined within the package like this:

Code: Select all

// contents of SuperDupaPackage.php
require_once 'SuperDupa_Foo.php';
require_once 'SuperDupa_Bar.php';
require_once 'SuperDupa_Zim.php';
require_once 'SuperDupa_Gir.php';
require_once 'SuperDupa_Pie.php';
require_once 'SuperDupa_Pow.php';
but you only make use of Foo:

Code: Select all

// contents of index.php
require_once 'SuperDupaPackage.php';
$a = new SuperDupa_Foo();
is there a performance hit from requiring all those classes without making use of them?

Posted: Tue Jul 18, 2006 1:26 pm
by feyd
There is a hit, yes.. but not too much unless your OS has issues with seeking to the files or php has problems (or bottlenecks) in read the files. In the end, it is highly dependant on how much and of what complexity the code is in each file.

Posted: Tue Jul 18, 2006 1:38 pm
by Christopher
Given that you used the word package "in the loose sense of the word" I would be suspicions of your design. Perhaps there is a better way to achieve what you are trying to do. Questions like this sometimes indicate that there is a problem.

Re: Performance Implications of Requiring Many Class Definit

Posted: Tue Jul 18, 2006 3:15 pm
by Roja
ole wrote:is there a performance hit from requiring all those classes without making use of them?
Yes, and because you specifically mentioned classes, I can confirm that it can be a non-trivial performance impact.

But as with anything performance related, your goals, your design choices, and so much more all come into play. You will need to be (much) more specific if you want a more specific answer.

With that said, as a general statement, yes - including multiple class files (even if you don't call them/use them) does add overhead.

Posted: Tue Jul 18, 2006 7:24 pm
by Ollie Saunders
arborint wrote:Given that you used the word package "in the loose sense of the word" I would be suspicions of your design.
I said "in the loose sense of the word" because I really don't fully understand what the definition of a package is and I suspect that it is exclusive to PEAR. But what I am making is a single class hierarchy.
perhaps there is a better way to achieve what you are trying to do. Questions like this sometimes indicate that there is a problem.
My hierarchy currently has 23 files (one class per file). I just wanted to know if I could provide the users of the package with a single file to include all the files. Seeing as feyd says there is a hit, I am now going to the effort of writing require statements above each class that extends another:

Code: Select all

require_once 'Another.php'; // this wouldn't of been necessary if all the classes were loaded in the right order by a master including file
class SomeClass extends Another {
and implementating a couple of functions which people will be able to use in their __autoload()

Code: Select all

/**
 * To assist those using __autoload(). Returns whether the class name
 * is an OsisForm class
 *
 * @param string $className
 * @return bool
 */
static public function isDecendentClass($className)
{
	return substr($className, 0, strlen(__CLASS__)) == __CLASS__;
}
/**
 * Load an OsisForm class
 * 
 * @param string $className
 * @return void
 */
static public function loadClass($className)
{
	$className = str_replace('_', '/', $className) . '.php';
	require_once $className;
}
But as with anything performance related, your goals, your design choices, and so much more all come into play. You will need to be (much) more specific if you want a more specific answer.
What makes you think I want a more specific answer?
What do you suspect I am doing wrong?
Basically I don't really understand why you made that statement.

Posted: Tue Jul 18, 2006 8:52 pm
by Jenk
Could you explain the purpose of the isDescendantClass method, please?

Just out of curiosity. I don't see why you want to compare length of $className and __CLASS__ as well as content, as well as I don't see why you would want to have the method at all, because the __CLASS__ will of course only ever be the name of the class in which the method resides :)

Purely observational curiosity, no flames :)

Thanks. :)

Posted: Tue Jul 18, 2006 9:02 pm
by Ollie Saunders
All the OsisForm classes are prefixed with OsisForm (like OsisForm_Select) so you can use that to work out which classes are OsisForm classes:

Code: Select all

function __autoload($class) {
	$ext = '.php';
	if (substr($class,0,4) == 'Zend') {
		Zend::loadClass($class);
		
	} else if (OsisForm::isDecendentClass($class)) {
		OsisForm::loadClass($class);
		
	} else if (Tilling::isDecendentClass($class)) {
		require_once '../app/class/' . $class . $ext;
		
	} else {
		require_once $class . $ext;
	}
}
the isDescendantClass method is defined within a class called OsisForm (without any suffix) which is kinda like the master class for them all.

Posted: Wed Jul 19, 2006 3:39 am
by Jenk
Aha, got ya :)

Would interfaces not be a better option?

Posted: Wed Jul 19, 2006 3:43 am
by Ollie Saunders
how?

Posted: Wed Jul 19, 2006 4:00 am
by Jenk

Code: Select all

interface iBar
{
    public function doSomething ();
}

class Foo implements iBar 
{
    public function doSomething ()
    {
        echo 'Hello World!';
    }
}

class FooBar
{
    private $obj;
    public function __construct (iBar $obj)
    {
        $this->obj = $obj;
        $this->obj->doSomething();
    }
}

$foobar = new FooBar(new Foo); //works
$foobar2 = new FooBar(new SomeOtherClass); //fails
:)

Posted: Wed Jul 19, 2006 4:36 am
by Ollie Saunders
Yeah jenk, i still don't see how that helps. An __autoload() function only has a single parameter and that is a string, so you can't test it for a type otherwise I would obviously be using instanceof.

Posted: Wed Jul 19, 2006 4:47 am
by Jenk
Ah yes.. sorry, I was getting it muddled :)