Jump to content

Function size, parsing


LittleJoe

Recommended Posts

I'm designing a feature-rich website with object-oriented PHP and I have a performance question. My background is in C, C++ and C# (.NET) programming. Now all those are compiled whereas PHP is interpreted. The following require_once statements are at the top of each page:

<?phprequire_once "_php/library/Session.php"; // Session class (session related functionality)require_once "_php/library/Databases.php"; // Databases class (database related functionality)require_once "_php/library/DatesTimes.php"; // DatesTimes class (date and time related functionality)require_once "_php/library/User.php"; // User class (user related functionality)require_once "_php/library/Page.php"; // Page class (page related functionality)require_once "_php/library/common.php"; // general functions?> // (X)HTML 5 code

Now some of those files are large and have a lot of methods/functions that are rarely used but it makes sense to keep them there because of the design principles of OOP. However, where OOP shines the best is in languages such as C# where only the necessary parts of the application is loaded into memory (on the as-needed basis). My question is, will the PHP engine have to waste a lot of CPU parsing through the classes and their methods every time a page is requested even though they're not being used or is there only a performance cost when the methods are being envoked (this parsing is not necessary in C# because the code has already been compiled)? I'm just wondering if I should break down the OOP architecture into smaller units that don't make as much sense logically but do make sense performance-wise.

Link to comment
Share on other sites

"A lot" is relative, but it will in fact use time and resources to load those classes. Let me point you to the SPL (standard PHP library) autoloading functionality, to only load a class when it is needed. Make sure you use the SPL variety (e.g. spl_autoload_register), not the earlier version of autoloading (__autoload). http://www.google.co...channel=suggest SPL in general would be a good thing for someone with your background to look into, it doesn't get taught a lot in most PHP tutorials but it is very powerful, useful, and focused on efficiency. SPL contains several data structures, iterators, interfaces, etc that you can use. If you're working with files, look into the SPL file handling classes instead of the regular C-library fopen stuff. http://www.php.net/m...en/book.spl.php

  • Like 1
Link to comment
Share on other sites

"A lot" is relative, but it will in fact use time and resources to load those classes. Let me point you to the SPL (standard PHP library) autoloading functionality, to only load a class when it is needed. Make sure you use the SPL variety (e.g. spl_autoload_register), not the earlier version of autoloading (__autoload). http://www.google.co...channel=suggest SPL in general would be a good thing for someone with your background to look into, it doesn't get taught a lot in most PHP tutorials but it is very powerful, useful, and focused on efficiency. SPL contains several data structures, iterators, interfaces, etc that you can use. If you're working with files, look into the SPL file handling classes instead of the regular C-library fopen stuff. http://www.php.net/m...en/book.spl.php
Well in my case all the classes are used but they contain a lot of methods that are not used but rarely. I'm worried that PHP might use a lot of CPU to parse them all before interpreting the ones it needs to use in each instance.
Link to comment
Share on other sites

How many classes are we talking about anyway? PHP is very fast at parsing. Most penalties come upon the use of a component, be it a method or a class. It will take more than 1000 classes before the loading time alone becomes significant. In terms of usage, YMMV, but typically somewhere around 100 classes is where things become noticeably slower (although still bareable), and you need to implement some sort of a caching mechanism. (Note: These numbers assume classes with methods of typical lengths - between 10 and 100 lines; not "monster" classes, or a class with a "monster" method; also, no connects with external sources, such as a database, since that's most often THE bottleneck, and would be so even in a compiled code)

  • Like 1
Link to comment
Share on other sites

How many classes are we talking about anyway? PHP is very fast at parsing. Most penalties come upon the use of a component, be it a method or a class. It will take more than 1000 classes before the loading time alone becomes significant. In terms of usage, YMMV, but typically somewhere around 100 classes is where things become noticeably slower (although still bareable), and you need to implement some sort of a caching mechanism. (Note: These numbers assume classes with methods of typical lengths - between 10 and 100 lines; not "monster" classes, or a class with a "monster" method)
Well those 6 require_once files have a class each except for "common.php" which has random functions that don't need to become methods in their own class. But as I said before, each class is loaded with methods that are not used often but there are always some methods used in each class (that is per HTTP request). Edited by LittleJoe
Link to comment
Share on other sites

You can time it yourself how long it takes to load the various classes using the microtime function. Create a blank page that does nothing except call microtime twice and report the difference which you can use as a baseline, then different versions that load one or more classes. It will be hard to test that accurately because you would normally use a loop to test many times, but you can't load a class in a loop because there's no way to unload or redefine a class.

  • Like 1
Link to comment
Share on other sites

You can time it yourself how long it takes to load the various classes using the microtime function. Create a blank page that does nothing except call microtime twice and report the difference which you can use as a baseline, then different versions that load one or more classes. It will be hard to test that accurately because you would normally use a loop to test many times, but you can't load a class in a loop because there's no way to unload or redefine a class.
Well the only problem is that I don't really know what is a lot of time in PHP terms. Other things need to be taken into consideration as well. I imagine that the server (Apache, MySQL) will behave differently when it recieves one request on my localhost compared to thousands of requests per second when in production.
Link to comment
Share on other sites

For what it's worth, the main application I work on loads quite a few things for every request:

require_once 'functions.global.php';require_once 'class.db.php';$db = new lms_database($config['db_host'], $config['db_user'], $config['db_pass'], $config['db_name']);require_once 'class.lang.php';$lang = new lms_lang();if (!$php_command_line){  require_once 'class.session.php';  $sess = new lms_session();} else {  $sess = null;}require_once 'class.userfield.php';require_once 'class.userfields.php';$uf = new lms_userfields();require_once 'class.config.php';$opts = new lms_config();require_once 'class.datacache.php';$cache = new lms_datacache($config['cache_timeout']);require_once 'class.lms.global.php';$global = new lms_global($db, $lang, $sess, $uf, $opts, $cache);if (!is_null($sess)) {  require_once 'factory.userpermissions.php';  $perms = lms_permissionsFactory::build($global, $sess);  $global->setPerms($perms);}require_once 'functions.usergroups.php';require_once 'functions.images.php';require_once 'functions.content.php';require_once 'functions.emails.php';require_once 'functions.dates.php';require_once 'functions.change-logs.php';require_once 'Json.php';

All of those files get loaded for every request, no matter how small. Some of those class files include other classes. The total size on disk for all of those class and function files is a little over 250KB.

  • Like 1
Link to comment
Share on other sites

The servers that run that application average around 12 requests per second in total. Personally, I don't think reducing the size of include files or splitting them up into multiple small pieces is going to help efficiency, it's going to be less efficient to include 10 small files than 1 large one because of disk overhead. The bottlenecks of PHP applications these days tend to be in the third party services they consume, from the database to filesystem to ajax requests. Database access time is the #1 thing that slows our application down, we get massive gains when we upgrade the storage system and increase the RAM cache for the database. The servers with 24GB of RAM reserve at least 16GB of it for database caching, and we have large SSD storage that is reserved for temp database storage, for temporary tables and things like that. Memory-only key/value databases or document databases like MongoDB or memcached can also be used for specific purposes to help avoid normal database connections and requests.

  • Like 1
Link to comment
Share on other sites

For what it's worth, the main application I work on loads quite a few things for every request: All of those files get loaded for every request, no matter how small. Some of those class files include other classes. The total size on disk for all of those class and function files is a little over 250KB.
Well my class libraries are still tiny then. Windows says 25.3 KB and 40.0 KB (size on disk). Then when I add third-party libraries to my site such as PHPMailer and perhaps GeoPlugin the size will grow considerably but I won't need them for every request.
Link to comment
Share on other sites

It's not up to you to set up HHVM. It's up to said shared host to do that, and most don't, since that's not "the" PHP interpreter, and their clients will likely complain because of that.

Link to comment
Share on other sites

If I have statement such as:

if ($something){include "large.php";}else{include "tiny.php";}

Does the PHP engine parse through both files even though it doesn't use one of them when it begins to execute (interpret) the statement?

Edited by LittleJoe
Link to comment
Share on other sites

It parses only the included file.But keep in mind that parsing a file you're not using can sometimes be faster than including the file conditionally, especially if your check requires a lookup in a file or database.So make sure to minimize such checks, or better yet - actually benchmark how much each option affects you.

Link to comment
Share on other sites

We're always talking about file contents. The name of a file is nothing more than a string in PHP.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...