Two and a half years ago, when first wrestling with the Tagged codebase, I asked Andrei about replacing all my PHP includes with __autoload. I was told under no uncertain terms to not do this.
It’s not that Andrei is wrong in his admonition. Far from it! For reasons that I don’t quite care to know, there are caching and lookup optimizations that APC cannot do when it has to switch context to run __autoload. But the problem in practice was two-fold:
- The company was bug-driven and the easiest way to eliminate an “Undefined class” error was to go into the preinclude script and include it. Voilá! problem solved at the expense of code bloat. (This bug happens often when deserializing nested objects from cache.)
- There are slowdowns when you use include_once where include would do, or when you don’t use the full path in your include, or when you construct your full path from symbols. How many of us do this? Heck, I’m still trying to get used to the idea of include_once and require_once. Ahh the days when I’d have to write symbols with every include file!
- More to the previous. If you have deep dependencies and don’t use a FrontController pattern, you’re going to have to use require_once() which will get executed multiple times. An __autoload only gets executed once.
At a certain point, optimization gives way to convenience and practicality.
For Tagged, this was that PHP would allocate 12MB/80ms to say “hello world”, 20MB/465ms to display the homepage, and 22MB/1965ms/1207ms to return my profile page
After the rewrite it takes 0.3MB/3ms to say hello world and 3.7MB/109ms to return my profile page.