Hi, I developed small application in php to make timing of entire collection of drupal functions. May be it yet exists but i've not found anywhere. I've inspired in articles from
http://2bits.com/articles/drupal-performance-tuning-and-optimization-for...
I really need a faster drupal!! It is very very slow (I use D6). I've made this piece of code to help optimizing and find bottlenecks. This code inserts timer_start() and timer_stop() in all functions, in the drupal codebase and in all the installed contributed modules!!
It also removes all the comments // and inserts a timer_stop() before any return statement.
Some functions are leave unmodified, because the algorithm of substitution is very complicated, and it fails the parsing in some conditions (for example, when there are characters {}; inside a string).
Steps for installation are:
- Make a backup of entire drupal. This script will modify ALL SOURCE CODE, inclusive the contributed modules.
- Create a setup_timers.php or copy attached file (rename to .php) and place it in drupal base root (same folder as index.php)
- Run the setup_timers.php ONLY 1 TIME!
- Modify the index.php file with the code below.
- Load any page. At end it shows the accumulated time of each function.
- May be you must repair any generated bug at the source code (nothing is perfect)
I tested it with drupal 6.8.
setup_timers.php:
function replace_returns($m) {
//print ">> replace_returns<br>";
//print '<pre>'.var_export($m, true).'</pre>';
$matches = array();
$matches2 = array();
$matches3 = array();
$r1 = preg_match('/\bpreg/', $m[3], $matches);
$r2 = preg_match('/\x{22}[^\x{22}]*(\x{2f}\x{2f}|;)[^\x{22}]*\x{22}/', $m[3], $matches2);
$r3 = preg_match('/\x{27}[^\x{27}]*(\x{2f}\x{2f}|;)[^\x{27}]*\x{27}/', $m[3], $matches3);
if($r1||$r2||$r3) {
//print '<pre>'.var_export($matches3, true).'</pre>';
print "@function $m[1](...) : Possible code breaking, leaving unmodified<br>";
return $m[0];
}
// alternative pattern for comments /\*(?:.|[\r\n])*?\*/
$new_body = preg_replace('/((?:\/\*(?:[^*]|(?:\*+[^*\/]))*\*+\/)|(?:[^\:]\/\/.*))/', '', $m[3]);
$new_body = preg_replace('/([^$]\breturn\b[^;]*;)/', '{timer_stop(\''.$m[1].'\'); $1}', $new_body);
return "function $m[1]$m[2]{timer_start('$m[1]');$new_body timer_stop('$m[1]');}";
}
function setup_timers_file($filename) {
if(!filesize($filename))
return;
$contents = file_get_contents($filename);
//print "Changing $filename...<br>";
//print "Contents: {len=". strlen($contents)."} <pre>".preg_replace('/\<\?php\b/','',$contents) ."</pre><br>";
(THE CODE IS NOT SHOWN CORRECTLY AT NEXT LINE, PLEASE, DOWNLOAD ATTACHED FILE)
$contents = preg_replace_callback('/***************/', 'replace_returns', $contents);
file_put_contents($filename, $contents);
//print "Contents: {len=". strlen($contents)."} <pre>".preg_replace('/\<\?php\b/','',$contents) ."</pre><br>";
print "Changed $filename<br>";
}
function setup_timers_dir($dir) {
if(!is_dir($dir))
return;
$dir=realpath($dir);
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
//$filename = realpath($dir . "//" . $file);
$filename = $dir . "\\" . $file;
if(filetype($filename) == "dir") {
if($file!="."&&$file!="..")
setup_timers_dir($filename);
}
else {
$path_info = pathinfo($filename);
if($file!="bootstrap.inc" && in_array($path_info['extension'], array("install", "php", "module", "inc")))
setup_timers_file($filename);
else
print "Jumping " . $filename ."<br>";
}
}
closedir($dh);
}
}
setup_timers_dir(".");
index.php modified (at end):
...
drupal_page_footer();
function cmp_timers ($a, $b) {
return ($a['time'] > $b['time']) ? -1 : 1;
}
print "page: ". timer_read("page") . " ms<br>";
uasort($timers, 'cmp_timers');
foreach ($timers as $t => $v) {
print "$t: " . $v['time'] . " ms<br>";
}
Please, anyone, make me happy, and optimize Drupal!
(first you can optimize or upgrade this code)
Regards
| Comment | File | Size | Author |
|---|---|---|---|
| index.php_.txt | 1.2 KB | msoler75 | |
| setup_timers.php_.txt | 2.2 KB | msoler75 |
Comments
Comment #1
msoler75 commentedI've upgraded the code (I'll post it when ready). Now it modifies more functions with the timer ops.
I tested on my drupal project, in the frontpage.
The frontpage has 5 blocks, 4 of them are views-blocks, a node-page, and some devel information.
I loaded some times without cache (only mysql query cache) but with eaccelerator.
I always obtained similar results:
page: 7392.04 ms
views_block: (6 calls) 3518.49 ms
execute_display: (6 calls) 2803.13 ms
template_preprocess_page: (1 calls) 2786.28 ms
theme_blocks: (25 calls) 2709.11 ms
block_list: (25 calls) 2666.56 ms
node_invoke_nodeapi: (41 calls) 1683.15 ms
node_load: (43 calls) 1674.19 ms
_db_query: (597 calls) 1562.69 ms
build: (6 calls) 1355.52 ms
template_preprocess_views_view: (6 calls) 1271.56 ms
media_mover_api_nodeapi: (41 calls) 1070.17 ms
media_mover_api_node_files_fetch: (21 calls) 1066.33 ms
init_query: (6 calls) 1013.79 ms
_views_fetch_data: (72 calls) 1012.91 ms
cache_set: (23 calls) 998.64 ms
content_views_data: (1 calls) 898.42 ms
node_view: (10 calls) 887.8 ms
t: (2542 calls) 594.12 ms
content_views_field_views_data: (170 calls) 540.55 ms
views_get_view: (6 calls) 519.25 ms
&views_get_default_view: (6 calls) 485.09 ms
views_discover_default_views: (6 calls) 484.62 ms
_views_discover_default_views: (1 calls) 483.05 ms
drupal_bootstrap: (3 calls) 381.41 ms
_drupal_bootstrap: (9 calls) 380.81 ms
_views_create_handler: (126 calls) 344.32 ms
poll_block: (2 calls) 328.95 ms
phptemplate_username: (26 calls) 303.61 ms
template_preprocess_node: (10 calls) 290.29 ms
url: (213 calls) 275.77 ms
db_query: (588 calls) 269.87 ms
theme_imagecache_formatter: (4 calls) 266.11 ms
cache_get: (63 calls) 258.98 ms
drupal_get_path_alias: (258 calls) 244.12 ms
template_preprocess_views_view_table: (1 calls) 241.64 ms
drupal_lookup_path: (377 calls) 233.14 ms
module_implements: (210 calls) 230.42 ms
content_allowed_values: (199 calls) 224.28 ms
init_handlers: (6 calls) 212.48 ms
_init_handler: (30 calls) 207.39 ms
&new_display: (37 calls) 205.14 ms
get_handlers: (30 calls) 200.26 ms
node_build_content: (10 calls) 200.16 ms
drupal_get_form: (3 calls) 197.12 ms
locale: (2542 calls) 196.49 ms
set_default_options: (126 calls) 196.1 ms
module_load_all: (1 calls) 195.44 ms
override_option: (233 calls) 191.59 ms
menu_tree: (4 calls) 174.26 ms
search_block: (1 calls) 161.83 ms
...
------------------------------------------------------------------------
I see some things...
*media_mover_api_nodeapi: (41 calls) 1070.17 ms
*media_mover_api_node_files_fetch: (21 calls) 1066.33 ms
In the front page I have any file nor media nor file listing. Then, why it spends 1 or 2 secs "moving media files"? I'll investigate and maybe I will uninstall this module.
*init_query: (6 calls) 1013.79 ms
What is this function? It spends much time (168ms per call).
*t: (2542 calls) 594.12 ms
¿Always must spend half a second for traslating the page? The texts are always the same. Then why a 1/2 sec?
*node_load: (43 calls) 1674.19 ms
It is 39ms per node. It's very good.
*_db_query: (597 calls) 1562.69 ms
It is 2ms per query. The query cache is running!
---------------------------------------------------------
Regards
Comment #2
damien tournoud commentedAre you running Drupal on a CPC-6128? Those timings appear to be *way* off.
Plus, you should better use xdebug's profiling mode for this kind of analysis.
Comment #3
msoler75 commentedI run on P4VM800 Intel 4 2000MHz PC, Windows, lighthttpd, drupal with 90 contributed modules, 20 users, 100 nodes...
When I run this drupal project in a web server (shared hosting), the timing values are similar or worse.
Thanks for the xdebug information, I'll try it.
For now, I detected some bottlenecks with my code and fixed them.
For example, in function mediamover_nodeapi... it spends much time for ALL LOADing nodes!!?, I rewritted to execute code only in the appropiate $node->type values. This kind of things I fixed, gaining 1-2 seconds.
Regards.
Comment #4
jody lynnThis does not seem to be a core issue.