Mantis - Quercus
|
|||||
Viewing Issue Advanced Details | |||||
|
|||||
ID: | Category: | Severity: | Reproducibility: | Date Submitted: | Last Update: |
2981 | minor | always | 09-30-08 08:40 | 10-08-08 18:48 | |
|
|||||
Reporter: | ferg | Platform: | |||
Assigned To: | ferg | OS: | |||
Priority: | normal | OS Version: | |||
Status: | closed | Product Version: | 3.2.1 | ||
Product Build: | Resolution: | fixed | |||
Projection: | none | ||||
ETA: | none | Fixed in Version: | 3.2.1 | ||
|
|||||
Summary: | 0002981: include performance issues | ||||
Description: |
(rep by Steven Grimm) Over the weekend I did a little bit of profiling of Quercus. There are two hotspots where Quercus is spending a lot of time when it goes through our big big list of include files. My test was just running "ab" to serially fetch a dummy .php file that contained nothing but an include_once of our top-level master include file. First, Quercus is checking the modification times on each original PHP file on every run. I don't see a config option to only do that periodically (though I may have missed something obvious) -- it's actually quite expensive, accounting for nearly 1/4 of the wall time of my test. That's possibly not a huge deal in a development environment but in a production environment we'd probably want to only check mod times once a minute or so since on-the-fly edits are extremely rare. Second, it's spending tons of time assembling the include file paths. To support multiple developer sandboxes, our include statements are all dynamic, like: include_once $_SERVER['PHP_ROOT'] . '/lib/display/pages.php'; and we set PHP_ROOT in the Apache virtual host config (on vanilla PHP) or in the Resin config. That ends up generating Java code like: env.includeOnce(_quercus_selfDirectory, v__SERVER.get(qv_PHP_ROOT_0).toStringBuilder(env).append(_qc_libdisplaypagesphp).toString(), false); According to the profiling, a huge amount of time is being spent in the various parts of that chain of string operations, primarily in the append() method which appears to need to do a reallocation of its buffer for each and every one of these includeOnce() calls. This may be related to bug 2971. Maybe this can instead do some compile-time evaluation of the paths, like: if (v__SERVER.get(qv_PHP_ROOT_0).equals("/path/at/compile/time")) { env.includeOnce(_quercus_selfDirectory, "/path/at/compile/time/lib/display/pages.php", false); // and ideally all the other adjacent includes that depend only on $_SERVER['PHP_ROOT'], // though the get().equals() is probably not too expensive to do for each one } else { // do the dynamic include as above, *and* trigger a background recompile of the page } That would basically eliminate the string construction cost of all these includes, of which we have zillions since each module "include_once"s its direct dependencies whether or not those dependencies were already included earlier in another module. (There are currently 18094 include_once statements in our code base, to give you some idea, though not all of them are hit on every request.) But maybe there's another way to make this fast; the above is just the first thing that comes to mind. Once we have a fix for 2971 in hand, and hopefully for the issues above too, we'll do another round of benchmarks/profiling and see where things stand. |
||||
Steps To Reproduce: | |||||
Additional Information: | |||||
Relationships | |||||
Attached Files: | bench.php [^] (1,412 bytes) 10-05-08 12:25 |
Notes | |||||
|
|||||
|
|
||||
|
|||||
|
|
||||
|
|||||
|
|