Do PHP Opcode Cache Work with _Autoload

Do PHP opcode cache work with __autoload?

(Disclaimer : I only know APC)

What an opcode cache do is :

  • when a file is included/required, it take the full path to that file
  • check if the opcodes corresponding to that file are already in RAM (in opcode cache)

    • if yes, return those opcode so they are executed
    • if no, load the file and compile it to opcodes ; and store opcodes in cache.

The important point, here, is the entry point : the full path to the file.


What autoloading generally do is :

  • get the name of a class
  • transform it to the name of a file
  • include/require that file

So, the informations that are relevant for the opcode cache (full path to the file, and the fact that it is included/required) are still here.

In consequence, autoload shouldn't bring any trouble with op code caching.

(And, when using APC, it doesn't, as far as I can tell)

PHP5 Frameworks: Autoloading and Opcode Caching

There seems to still be confusion about this topic, however in most cases it comes down to ease vs performance.

A good mailing list thread to read would be this one on Zend Frameworks mailing list:

http://n4.nabble.com/ZF-and-Autoloading-td640085i20.html

Now, the correlation is here because if you inherit from not-yet-defined
class, you might rely on autoload to define it (though you might also
rely on include), and actually the presence of the autoload facility may
encourage you to use such inheritance. But this is not the autoload
which brings trouble (see after Ramus' "it's not just autoload" in the
blog for some examples of troublesome things).
So the right phrase would be "people which tend to rely on autoload tend
also to use code which defies compile-time binding". Which can't be seen
as autoload fault, of course, and just avoiding autoload won't help a
bit with that - you would also have to rewrite your code so that
compile-time binding could happen. And it has nothing to do with uses of
autoload with "new", for example.

As for the slowdown from the effects described above - i.e., absence of
the compile-time binding - the code indeed becomes a bit slower and such
code can lead in some obscure cases to some trouble to opcode caches
(not in the autoload cases - but in cases where classes are defined
inside conditions, or, God forbid, different definition is created
depending on condition) - but it has next to nothing to do with using
autoload by itself.
The amount of slowdown, however, seem to be greatly exagerrated by
people - it is nothing (and I repeat to be clear - NOTHING) compared
to the performance benefit given by the opcode cache due to the absence
of the disk operations and compilation stage. You could probably
compose an artificial benchmark that would show some significant
slowdown, but I do not believe any real application would even notice.

source: http://n4.nabble.com/ZF-and-Autoloading-td640085i20.html#a640092

use of php spl_autoload_unregister

You can specify more than one autoload method. So if you have an application that has a lot of autoload methods, it's possible you would want to unregister those methods as well. In practice, this method likely exists more for completeness (not too many projects use so many methods that you would want to unregister an autoload method).

Opcode caching is a different topic. This has nothing to do with autoloading. When PHP is told to execute a file it first parses the file and builds machine level instruction code (operations code, or opcode). The second pass executes the machine level code. Opcode caching (APC, Zend Opcache, etc) simply stores the machine level code so you only need to execute it the next time you call that page, and thus save yourself the extra processing.

Expanded for the comment

You can include all the files if you want, but autoloading does two important things

  1. You can structure your classes within a namespace and use files and
    directories to mirror the namespace structure. This makes working with your classes very easy because you can tell quickly where each class file lives
  2. You're including files only as you need them

As for your opcache, your thinking is incorrect. Let's say you include all classes and methods you use. Now, let's say you have a page that only uses 25% of your code base. That means you loaded the other 75% and forced the opcache to cache it. But to what end? Opcache works on a file-by-file basis, not a project level basis. So you would be bloating your code on every page for no gain because autoloading would have included the code you needed anyways, but dynamically.

PHP __autoload performance

If you want to avoid __autoload, you can use require_once instead of include.

The performance hit of using __autoload may be considerable, especially because some opcode caches do not support it properly. However, given it's very handy, I'd say use it unless your opcode cache does not cache autoload includes.

Do you really need to Auto-load ALL pages of a Class-based site on every pageload?

That's a confusing name for the file, as autoloading is a mechanism in PHP that allows you to load classes as and when they are needed, a good solution when you have many classes and only a few will be needed for each execution.

For example:

function autoload($class_name) {
$file = "classes/$class_name.php";

// You could add some checks here (e.g. whether the file exists, whether the
// class indeed exists after the file is loaded) to facilitate better errors,
// of course this would marginally increase the time needed to load each class.

require $file;
}

// Register the `autoload` function with PHP's autoload mechanism
spl_autoload_register('autoload');

// This will execute `autoload('Class')` (unless `Class` is already defined)
$instance = new Class;

So, to answer your questions:

  1. It is not necessary to load them all, however classes that are used must be available, either by loading them all together (current situation), loading them conditionally (if(p == 'whatever') require 'classes/whatever.php'), or by using autoloading.

  2. There is some delay whenever a file is included as the file must be parsed/executed. PHP is fairly fast but still, including files you do not need is a waste. If you're using bytecode caching, the retrieved bytecode must still be executed.

  3. That is one avenue of improvement, autoloading presents a more dynamic alternative.

  4. Dependencies may be a problem if any of your page classes depend on another class, as your conditional loading could get very bloated.

Also a little additional material regarding bytecode caching, if you're using it:

  • PHP5 Frameworks: Autoloading and Opcode Caching
  • Do PHP opcode cache work with __autoload?

The summary seems to be that, as long as you use include or require to load the file, bytecode caching will work as intended.

Why all my files are not cached with apc op code?

For some reasons apc.cache_by_default was set to OFF, an my files were not getting cached correctly, which is logical given this config, however, I still don't understand why those I manually required was actually cached.

Does autoload really kill performance when using APC(latest versions/up to date). Benchmarks?

Personally, I don't believe relying on __autoload() is good practice. PHP is a loosely typed language, not a lazily typed language. :)

Check out some performance here:

  • http://weierophinney.net/matthew/archives/245-Autoloading-Benchmarks.html
  • http://www.ilia.ws/files/zend_performance.pdf

Rasmus's answer on this (which you also found) was my guidline through all this years:

<arnaud_> does autoload have a performance impact when using apc ?
<Rasmus_> it is slow both with and without apc
<Rasmus_> but yes, moreso with apc because anything that is autoloaded is pushed down into the executor
<Rasmus_> so nothing can be cached
<Rasmus_> the script itself is cached of course, but no functions or classes
<Rasmus_> Well, there is no way around that
<Rasmus_> autoload is runtime dependent
<Rasmus_> we have no idea if any autoloaded class should be loaded until the script is executed
<Rasmus_> top-level clean deps would speed things up a lot
<Rasmus_> it's not just autoload
<Rasmus_> it is any sort of class or function declaration that depends on some runtime context
<Rasmus_> if(cond) function foo...
<Rasmus_> if(cond) include file
<Rasmus_> where file has functions and classes
<Rasmus_> or heaven forbid: function foo() { class bar { } }

Does autoload really kill performance when using APC(latest versions/up to date). Benchmarks?

Personally, I don't believe relying on __autoload() is good practice. PHP is a loosely typed language, not a lazily typed language. :)

Check out some performance here:

  • http://weierophinney.net/matthew/archives/245-Autoloading-Benchmarks.html
  • http://www.ilia.ws/files/zend_performance.pdf

Rasmus's answer on this (which you also found) was my guidline through all this years:

<arnaud_> does autoload have a performance impact when using apc ?
<Rasmus_> it is slow both with and without apc
<Rasmus_> but yes, moreso with apc because anything that is autoloaded is pushed down into the executor
<Rasmus_> so nothing can be cached
<Rasmus_> the script itself is cached of course, but no functions or classes
<Rasmus_> Well, there is no way around that
<Rasmus_> autoload is runtime dependent
<Rasmus_> we have no idea if any autoloaded class should be loaded until the script is executed
<Rasmus_> top-level clean deps would speed things up a lot
<Rasmus_> it's not just autoload
<Rasmus_> it is any sort of class or function declaration that depends on some runtime context
<Rasmus_> if(cond) function foo...
<Rasmus_> if(cond) include file
<Rasmus_> where file has functions and classes
<Rasmus_> or heaven forbid: function foo() { class bar { } }

php class autoload - seems to be caching?

I found the answer to this... and as usual with "bugs" that elude me for days, it turns out that I did something incredibly stupid:

It turns out that at some point in the past I accidentally uploaded a copy of class_web_page.php into the site home directory rather than the classes subdirectory. So it existed twice.

So, it would appear that despite my autoloader telling php to look in the classes subdirectory, it will look first in the same directory as the main script (index.php in the case of my site's home page). All of the other site page scripts are in subdirectories (forum, gallery, etc) so they were "correctly" using the /classes/class_web_page.php

I've now deleted the copy of class_web_page.php that was living in the home directory... and everything works as it should.

Is it bad to use autoloading in PHP?

Bad? No. __autoload() is one of my favorite additions to PHP 5. It removes the responsibility (and annoyance) of manually having to include/require the class files necessary to your application. That being said, it's up to you as the developer to ensure that only the 'appropriate classes' are loaded. This is easily done with a structured naming scheme and directory structure. There are plenty examples online of how to properly use __autoload(), do a Google search and you'll find plenty of information.



Related Topics



Leave a reply



Submit