16

I installed XHPROF to check how I could improve my code. I noticed that Drupal calls is_dir() over 4000 times on nearly every request, and this takes about 800ms.

screenshot

Why does this happen? Is there any way to speed that up?

I have already disabled the automatic register rebuilt, but it didn't decrease the number of times is_dir() is called.

2
  • What page are you looking at? Seems like it's caused by the file_scan_directory. Bet it's during cron or some administration page.
    – ram4nd
    Commented Jul 7, 2013 at 20:05
  • And this is how Drupal recognizes new modules, themes and libraries in different directories! Commented Jul 17, 2013 at 11:28

1 Answer 1

20

When you uninstall a module, you need to first disable it from admin/modules and then uninstall it from admin/modules/uninstall. The same goes for themes, which should be first disabled from admin/appearance.

If you, for example, delete the module without disabling the module, Drupal will continue to search for the module in the file system, which can result, among other errors, in the issue you are experiencing.

See also Avoid re-scanning module directory when multiple modules are missing.

To understand which module has been deleted without first uninstalling it, you will need to run the SELECT name, filename FROM system WHERE status = 1; query and compare that list of module with the modules present on the site directory. All the enabled modules and themes should be present.

There's also a hook implementation Martin_Dresden posted on Drupal 7 abysmally slow: file_scan_directory called > 1000 times per page load that may help with debugging. I provide here a slightly modified version.

function MYMODULE_init() {
  $startingtime = microtime(true); 
  $o = '<p>Checking for dead modules ...</p>';
  $result = db_select('system')
    ->fields('system', array('filename'))
    ->condition('status', '1', '=')
    ->execute();
  $n = 1;
  $m = 0;
 
  foreach ($result as $row) {
    $path = DRUPAL_ROOT . '/' . $row->filename;

    if (!file_exists($path)) { 
      $o .= "#$n $path<br>";
      $m++;
    }

    $n++;
  }

  $timedif =  round(microtime(true) - $startingtime,3);
  $o .= "Total of $n active modules registered in database. $m dead entries found.<br>";
  $o .= 'Query Time: ' . $timedif . ' seconds';
    
  drupal_set_message($o);
}
4
  • 1
    Is there a way to determine which row in {system} is the problem?
    – mpdonadio
    Commented Jul 8, 2013 at 2:01
  • @MPD answer updated with possible solution there. Commented Jul 8, 2013 at 4:14
  • If I disable a module but don't uninstall it, are there any disadvantages in this case compared to also uninstalling it?
    – Mario Awad
    Commented Jul 10, 2013 at 8:35
  • The module will have a row in system table! Un installation wipes everything related to the module in db and in file system if 'un install' routine is properly written! Commented Jul 17, 2013 at 11:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.