Every request a lot of code is interpreted but also a lot of this code isn't actually used for the current request. The most ideal situation would be that only necessary code is interpreted. D7 already has something to achieve this: registry.
Another improvement would be if functions that are only called in a combination (like hooks), also are combined into one file (and when thy have the same arguments, maybe even into one function) using code generation (only needs to be called when a module is enabled/disabled).
To illustrate this an example for hook-implementations:
modules/
example.module
example.hooks (move all hook-implementations of this module into this file)
Another option would be to move all non-hook-implementations to .inc files and leave hook-implementations in the .module file
When a module is enabled/disabled all hook-implementations are combined in files per hook (generated).
files/
code/
hooks/
menu.inc (containing all hook-implementations of all modules of hook_menu())
block.inc (containing all hook-implementations of all modules of hook_block())
etc...
Maybe it also possible to combine all hook-implementations into one function per hook; would be tricky because hook-implementations use the same scope then. On the other hand it would mean a very big performance improvement since function calls are time-consuming.
module_invoke($hook) then should include "file/code/hooks/$hook.inc" every time a new hook is used.
Since the original files aren't modified it is still possible to use the .hook file instead of the generated ones (useful for debug purposes).
Overall I think code generation could bring drupal a big performance improvement. Besides code generation for hook-implementations there are several other possibilities.
Comments
Comment #1
alanburke CreditAttribution: alanburke commentedComment #2
catchcasey - have you seen #345118: Performance: Split .module files by moving hooks and #340723: Make modules and installation profiles only require .info.yml files? I think much of what you're talking about other than the actual code generation is discussed there.
Being able to group all $module_nodeapi_load() and $module_form_alter() into a single file per hook sounds interesting, but I don't see how you'd get round the security issue of allowing Drupal write access to itself, nor the issue of duplicate function declarations between the original file and the hook.
Additionally, many modules implement upwards of 10 hooks each (not to mention using their API functions within hooks, which Drupal can't know much about, requiring the .module to be loaded too anyway. So at a certain point, the number of aggregated hook files which would need to be loaded might well end up equivalent to the number of .module files (or whichever files we end up loading when things have been split up properly for the registry) - and we wouldn't end up gaining anything. I think this issue is better handled in the two existing patches - where we can set up good conventions for contrib modules to follow and make improvements pretty much just by moving some code around. But leaving this open for more discussion.
Comment #3
casey CreditAttribution: casey commentedAh, no I didn't see these issues. But that is a good start for implementing code generation :)
1. security
Why is writing access a security issue? Code is only generated when modules are enabled/disabled (when drupal starts/stops using more/less code).
2. duplicate declarations
The original files shouldn't be loaded when the optimized ones are generated; that's why hook implementations have to be in a seperate file. You also could rename the generated functions by giving it a prefix to ensure to duplicate declarations.
You could also add an extra function to these files: module_invoke_$hook() with fixed calls to hook-implementations; no need for registry lookups.
3. loaded files
Most hooks aren't used every request (hook_menu() only for menu rebuild, hook_nodeapi() only for pages containing nodes, etc). So I guess it does bring down the number of included files.
4. API functions within hooks
Maybe hook-implementations should include their needed code, or use the registry.
Comment #4
catchAny solution which allows Drupal to write code to it's own directories which will subsequently be executed is going to be won't fixed - once apache has write access to those directories, then there are many potential ways code can be written to them, either from inside or outside Drupal itself depending on configuration. See the massive effort which went in to making http://drupal.org/project/plugin_manager into a secure solution for some of the arguments around this.
Comment #5
casey CreditAttribution: casey commentedOther possibilities:
- page callbacks could also be moved into seperate files (during code generation);
- theme() function can be hugely optimized using fixed calls in a generated version per theme.
Comment #6
casey CreditAttribution: casey commentedI see...
Maybe then Drupal should generate code when a module is enabled/disabed, provide it to the user to download and ask the user to upload it. Nah... don't think so :)
symfony-project uses code generation, for database models if I am right (called Propel I believe); that's where I got the idea from.
Comment #7
killes@www.drop.org CreditAttribution: killes@www.drop.org commentedThere is no code in here and it doesn't look as if we'd get any. There rest can be dealt with in #345118: Performance: Split .module files by moving hooks.
Comment #8
casey CreditAttribution: casey commentedWell, I've been testing some code generation techniques for Drupal 6; I created a module that copies the code of your drupal installation to a temporary directory. First it splits all functions and class into seperate files. Then it modifies the function calls so that functions gets loaded when needed.
It will decrease memory usage a lot! Especially when a great number of modules are installed.
WARNING Please don't try this module on your production website; it'll probably destroy it!
To try the module:
Note that this module is more of a proof of concept than an actual module! What do you think? Could be an alternative/addition to the registry in D7?
Comment #9
killes@www.drop.org CreditAttribution: killes@www.drop.org commentedI think it should be a contrib module.
Comment #10
CorniI CreditAttribution: CorniI commentedsubscribe
Comment #11
sunsubscribing
Comment #12
wuf31 CreditAttribution: wuf31 commentedMm..
Sounds interesting. Curious on how this is gonna turn up.
@casey, any progress on this one ?
Comment #13
catchThis is almost certainly a contrib project, but leaving open.
Comment #14
ClearXS CreditAttribution: ClearXS commentedSorry for my PHP/Apache etc. technical lackings, but in general:
Normally C programming (assembly language compiling) is much faster than basic; its important to compile everything when the program/module is ready to the assembly language form.
So how about Drupal, PHP in general? To me leaving a program in human language, sounds amateuristic. But those were ideas in the beginning of programming, for me some lblue monday long time ago.
Then indeed, Drupal is amazingly slow, considering the speed of a computer/server and other webware. Ofcourse only installing the basic core functions will be much faster. But I loaded my install with a lot of mods (in the lower hundreds, but many mods should be combined) to make some supersite. Not even that many, considering that there are thousands of Drupel mods. It took me years (by other reasons too) to get over this barrier of Drupal being nasty to accept installations, because it is slow. I had to put my memory up to 96M (now 500M), script time to 300. But that didn't work untill I added a seemingly undocumented rule in de settings.php for that script time too. Yes, something like cgi-php, I selected on Bluehost and I'm not sure if thats working now. For the normal php I did:
.htaccess:
php_value memory_limit 500M
php_value max_execution_time = 300
php_value max_input_time = 600
#php.ini:
max_execution_time = 300
memory_limit = 500M
max_input_time = 600
settings.php:
ini_set('memory_limit', '500M');
ini_set('max_input_time', '600'); (own idea; not documented?)
ini_set('max_execution_time', '300'); (own idea; not documented?)
Now most modules are active someway, my Drupal is very, very slow. It surpises me that my browser accepts these long times, but other users might have that problem indeed, or just walk out of this not wanting to wait that long.
(yeah, I have Bluehost, a dedicated probably is much faster)
I'm really amazed that experienced programmers -what I'm not- let this severe problem going on for years. Or did I miss something like nice theory, but in practice?
Anyway, just googling on this, first page:
* Compiling PHP and Apache 2 from source on Linux OS http://www.web-tech-india.com/articles/php/compiling_php_apache/
* Roadsend PHP compiler http://en.wikipedia.org/wiki/Roadsend_PHP
* phc -- the open source PHP compiler http://www.phpcompiler.org/
* http://en.wikipedia.org/wiki/PHP#Speed_optimization
Speed optimization
As with any interpreted language, PHP scripts are stored as human-readable source code and are compiled on-the-fly by the PHP engine. In order to speed up execution time and not have to compile the PHP source code everytime the webpage is accessed, PHP scripts can also be stored in binary format using PHP compilers such as phc and roadsend.
Code optimizers aim to reduce the runtime of the compiled code by reducing its size and making other changes that can reduce the execution time with the goal of improving performance. The nature of the PHP compiler is such that there are often opportunities for code optimization, and an example of a code optimizer is the eAccelerator PHP extension.
Another approach for reducing overhead for high load PHP servers is using an Opcode cache. Opcode caches work by caching the compiled form of a PHP script (opcodes) in shared memory to avoid the overhead of parsing and compiling the code every time the script runs. An opcode cache, APC, will be built into PHP 6. Opcode caching is also available in Zend Server Community Edition.
Sorry for my long reply, but I like to make the picture as complete as possible. So I hope for the feedback and OFCOURSE THIS NEW PROJECT/MODULE.
Is this an official project already? If not, how?
Thansk & good luck!
Comment #15
scroogie CreditAttribution: scroogie commentedClearXSClearXS, this is not the place to discuss this, but I can understand how you got mislead by the title. Those links you pasted are about technologies that need to be configured on the server site. If you know what you're doing, Drupal can be very fast. Of course you need decent hardware and some knowledge, but the same holds for every other major software product. Of course, you don't get a Porsche if you pay for a Citroën 2CV, but c'est la vie.
The core developers spend a LOT of time on performance optimizations. Plus, there are a lot of contrib projects that deal with performance. Have a look at some of the performance projects: http://drupal.org/taxonomy/term/123
Especially the following ones
http://drupal.org/project/Cacherouter
http://drupal.org/project/apc
http://drupal.org/project/memcache
http://drupal.org/project/fastpath_fscache
First, what you should do is identify your problem. First step should be to find out if it's the time PHP spends on the code or the database connections and querying thats pulling your site down. Second step is to invest some time to learn about possible optimizations.
Comment #16
ClearXS CreditAttribution: ClearXS commentedMany thanks! Indeed, it wasn't the proper place, but now this page is one of the most complete; so many others and I will easily get to this info again by a Google or Drupal search. However, think I just found the proper page:
Drupal caching, speed and performance http://drupal.org/node/326504
If so; that is the place where all this sort of info should be centralized and edited into (anyone can edit there).
Comment #17
markus_petrux CreditAttribution: markus_petrux commentedInteresting news, I think: Facebook has recently open sourced a new PHP compiler:
http://developers.facebook.com/news.php?blog=1&story=358
PS: Sorry, if this is Off Topic here. :-/ I haven't found any better Drupal core issue to post this.
Comment #18
alanburke CreditAttribution: alanburke commentedhttp://fourkitchens.com/blog/2010/02/03/making-drupal-pressflow-more-mun...
Comment #19
sunClosely related:
#1668892: Enable secure compiled information on disk
#1387776: Move some rebuilds outside of Drupal
Comment #32
smustgrave CreditAttribution: smustgrave at Mobomo commentedWonder if this is still needed with D10?
Comment #33
catchWe're on the way towards deprecating procedural hooks, and everything else these days is OOP, so I think this can just be marked outdated. #3366083: [META] Hooks via attributes on service methods (hux style).