Why would taxonomy_term_save be slow when called from hook_install_tasks? As part of making a site more easily deployable from scratch, I have generated two PHP scripts to pre-populate taxonomy vocabularies with a list of terms.  The scripts are straightforward, creating stdClass objects with the appropriate fields and callingtaxonomy_term_save on each one.  Example:

$term = (object) array (
  'name' =&gt; 'Art &amp; Architecture',
  'description' =&gt; '',
  'format' =&gt; 'plain_text',
  'weight' =&gt; '0',
  'vocabulary_machine_name' =&gt; 'categories',
  'field_cc_numeric_code' =&gt;
  array (
    'und' =&gt;
    array (
      0 =&gt;
      array (
        'value' =&gt; '102',
      ),
    ),
  ),
);
$term-&gt;vid = $vocabulary-&gt;vid;
taxonomy_term_save($term);


The variable $vocabulary already contains the appropriate taxonomy vocabulary structure at the time this is called.  One vocabulary has about 150 terms to create, the other about 2,000.

On a fresh installation of the site made using drush site-install, these scripts run almost instantly when called via drush php-script.  However, if they are incorporated into the installation profile and called by a task in the implementation of hook_install_tasks, they are much slower.  In the latter case, saving each term takes about a second, which is unacceptably slow.

There is discussion of a similar issue at https://www.drupal.org/node/1887924, but no solution offered either there or in the linked bug report.

Why would taxonomy_term_save be so much slower when performed from an installation task?  Is there anything that can be done about it?
In this case, the problem resulted from having the Pathauto module enabled during installation.  When a new taxonomy term is saved, Drupal calls pathauto_taxonomy_term_insert(), which calls pathauto_taxonomy_term_update_alias(), which in turn calls pathauto_create_alias().  This last function calls an internal function, _pathauto_path_is_callback(), to determine whether an alias can be created for a given path, and this in turn calls the core function menu_get_item(), which contains the following lines:

if (variable_get('menu_rebuild_needed', FALSE) || !variable_get('menu_masks', array())) {
  menu_rebuild();
}


menu_rebuild contains the following lines:

if (defined('MAINTENANCE_MODE')) {
  variable_set('menu_rebuild_needed', TRUE);
}
else {
  variable_del('menu_rebuild_needed');
}


The cumulative effect seems to be that the menu_rebuild_needed variable is continually reset to TRUE, meaning that a complete menu rebuild is triggered each time a new taxonomy term is saved, slowing things down immensely (from ~100 terms saved per second to ~1 per second).

This seems like a bug, though it's not clear which component, if any, is at fault.  For now, I am working around the problem by disabling pathauto, creating the terms, and then re-enabling pathauto:

module_disable(array('pathauto'));
…
module_enable(array('pathauto'));