views:

97

answers:

3

I'd like to check if my understanding's correct about require_once(). I have a bunch of functions in file foo.php. Let's say 7/8 out of them are always used, and one of them's rather rare and rather large. I have to keep this function's definition in foo.php. Can you tell me if the following approach achieves anything, and if you think it's worth what it achieves.

  • Take out the body of the function and put it in an external file.
  • Redefine the original function to require_once() that particular file and pass execution over to the helper function.

I understand this could save server memory on the requests where that function isn't run. What exactly am I saving though? Just the memory it takes to hold the body of the function? That would mean it would have to be a pretty big function before being worth it I guess. Also, if I'm using something like APC does it become less useful?

Please correct or add to this as appropriate!

Thank you very much.

+2  A: 

I highly doubt you will gain anything from refactoring it into a separate file. Also, do you actually have any problems with the code as it is now that makes you consider this? You know premature optimization is the root of all evil. Profile your code to see if and where it has bottlenecks before you waste your time on pointless µoptimizations.

Gordon
Yeah, I'm not trying to prematurely optimise so much as better understand PHP! I'm using Drupal which encourages for example having your code to generate admin pages in a separate file so that they're not always loaded when not being used. However if you want to modify another module's admin screens you need to use a hook, which needs to be in the main module file. That's what started me thinking - I'm not really trying to modify my project, just understand the issues. What exactly are you saving by following Drupal's policy and separating out admin functions?
Jes
@Jes if there's a defined group of functions you know for sure will never be used in the current script/task/file, I would indeed opt for not including them.
Pekka
@Jes I'm not familiar with Drupal, but I'd say they advise for that for reasons of maintainability and for separating concerns and responsibility. Admin is *admin*, so it should not be part of *regular*. If you separate responsibility this way, you are better off not including it when you dont need it, just like you wouldnt wear sunglasses when there is no sun outside. Performance wise, it depends on how many files are included and how many include pathes you've got, before it makes a notable difference though.
Gordon
+1  A: 

Update: From your comment to Gordon I see you're using Drupal: This method doesn't work there, because Drupal is heavily object-oriented already. What is described here is making use of the Autoloading mechanism for a function-based project using static classes.

As Gordon says, this will save memory only for really incredibly huge functions. In my experience, though, loading includes into memory takes up much more space than the exact number of bytes needed to hold the code. I'm not a PHP internals expert, but I assume the code is parsed or at least preprocessed either way.

Assuming your PHP application is entirely function-based with no OOP, one idea that comes to mind that you could use to split up your includes is putting your functions into classes, and making use of the autoloader mechanism:

class maintenance_functions
 { 

   public static function xyz() { ................  }

and start calling them statically:

 maintenance_functions::xyz();

one class would occupy one file.

Group all the rarely used functions into separate files.

Then, you could make use of the Autoloading mechanism. This will load needed classes automatically at the point they are needed. If I for example, call

 datamining_functions::xyz();

the autoloader will look for the file containing datamining_functions and include that. This eliminates the complete 'require()' hassle and lets you concentrate on how to group your functions most efficiently.

This is not a real transition to OOP: We just use class constructs to group the functions, in order to be able to use the autoloader. It should be possible to migrate functions into such classes without the need for major rewrites.

Pekka
Thanks, didn't know about autoloading! Still wondering if fundamentally the only resource used by having the function in the main module is just a bit of memory close to (if not exactly) the size of the function source code, or if there's more to it?
Jes
@Jes in my experience, huge amounts of code occupy a larger amount of memory than the actual bytes of code. I presume any code, whether used or not, has to be parsed at inclusion time. Parsing huge includes also takes time.
Pekka
PHP5 likes it if you use `public static function xyz() {` (Error when $this is used and prevents a E_STRICT notice)
Bob Fanger
@Bob good point, added.
Pekka
A: 

You should use Xdebug to find out the answer - worth or not is subjective.

tszming
Thanks, but I'm asking more experienced folks if _they_ think it's worth it!
Jes