Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.898
diff -u -p -r1.898 common.inc
--- includes/common.inc	12 May 2009 08:37:44 -0000	1.898
+++ includes/common.inc	16 May 2009 18:24:44 -0000
@@ -1882,6 +1882,7 @@ function drupal_page_footer() {
 
   module_implements(MODULE_IMPLEMENTS_WRITE_CACHE);
   _registry_check_code(REGISTRY_WRITE_LOOKUP_CACHE);
+  drupal_cache_system_paths();
 }
 
 /**
Index: includes/path.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/path.inc,v
retrieving revision 1.35
diff -u -p -r1.35 path.inc
--- includes/path.inc	7 May 2009 15:49:57 -0000	1.35
+++ includes/path.inc	16 May 2009 18:24:47 -0000
@@ -49,6 +49,9 @@ function drupal_lookup_path($action, $pa
   $map = &drupal_static(__FUNCTION__, array());
   $no_src = &drupal_static(__FUNCTION__ . ':no_src', array());
   $count = &drupal_static(__FUNCTION__ . ':count');
+  $system_paths = &drupal_static(__FUNCTION__ . ':system_paths');
+  $no_aliases = &drupal_static(__FUNCTION__ . ':no_alias', array());
+  $first_call = &drupal_static(__FUNCTION__ . ':first_call', TRUE);
 
   $path_language = $path_language ? $path_language : $language->language;
 
@@ -61,19 +64,45 @@ function drupal_lookup_path($action, $pa
     $map = array();
     $no_src = array();
     $count = NULL;
+    $system_paths = array();
+    $no_aliases = array();
   }
   elseif ($count > 0 && $path != '') {
     if ($action == 'alias') {
+      // During the first call to drupal_lookup_path() per language, load the
+      // expected system paths for the page from cache.
+      if ($first_call) {
+        $first_call = FALSE;
+        $map[$path_language] = array();
+        // Load system paths from cache.
+        $cid = current_path();
+        if ($cache = cache_get($cid, 'cache_path')) {
+          $system_paths = $cache->data;
+          // Now fetch the aliases corresponding to these system paths.
+          // We order by ASC and overwrite array keys to ensure the correct
+          // alias is used when there are multiple aliases per path.
+          $map[$path_language] = db_query("SELECT src, dst FROM {url_alias} WHERE src IN(:system) AND language IN(:language, '') ORDER BY language ASC", array(
+            ':system' => $system_paths,
+            ':language' => $path_language
+          ))->fetchAllKeyed();
+          // Keep a record of paths with no alias to avoid querying twice.
+          $no_aliases[$path_language] = array_flip(array_diff_key($system_paths, array_keys($map[$path_language])));
+        }
+      }
+      // If the alias has already been loaded, return it.
       if (isset($map[$path_language][$path])) {
         return $map[$path_language][$path];
       }
-      // Get the most fitting result falling back with alias without language
-      $alias = db_query("SELECT dst FROM {url_alias} WHERE src = :src AND language IN(:language, '') ORDER BY language DESC", array(
-        ':src' => $path,
-        ':language' => $path_language))
-        ->fetchField();
-      $map[$path_language][$path] = $alias;
-      return $alias;
+      // For system paths which were not cached, query aliases individually.
+      else if (!isset($no_aliases[$path_language][$path])) {
+        // Get the most fitting result falling back with alias without language
+        $alias = db_query("SELECT dst FROM {url_alias} WHERE src = :src AND language IN(:language, '') ORDER BY language DESC", array(
+          ':src' => $path,
+          ':language' => $path_language
+        ))->fetchField();
+        $map[$path_language][$path] = $alias;
+        return $alias;
+      }
     }
     // Check $no_src for this $path in case we've already determined that there
     // isn't a path that has this alias
@@ -103,6 +132,33 @@ function drupal_lookup_path($action, $pa
 }
 
 /**
+ * Cache system paths for a page.
+ *
+ * Cache an array of the system paths available on each page. We assume
+ * that aiases will be needed for the majority of these paths during
+ * subsequent requests, and load them in a single query during
+ * drupal_lookup_path().
+ */
+function drupal_cache_system_paths() {
+  // Check if the system paths for this page were loaded from cache in this
+  // request to avoid writing to cache on every request.
+  $system_paths = &drupal_static('drupal_lookup_path:system_paths', array());
+  if (!$system_paths) {
+    // The static $map array used by drupal_lookup_path() includes all
+    // system paths for the page request.
+    $map = &drupal_static('drupal_lookup_path', array());
+
+    // Generate a cache ID (cid) specifically for this page.
+    $cid = current_path();
+    if ($paths = current($map)) {
+      $data = array_keys($paths);
+      $expire = REQUEST_TIME + (60 * 60 * 24);
+      cache_set($cid, $data, 'cache_path', $expire);
+    }
+  }
+}
+
+/**
  * Given an internal Drupal path, return the alias set by the administrator.
  *
  * If no path is provided, the function will return the alias of the current
Index: modules/path/path.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/path/path.test,v
retrieving revision 1.11
diff -u -p -r1.11 path.test
--- modules/path/path.test	10 May 2009 16:50:19 -0000	1.11
+++ modules/path/path.test	16 May 2009 18:24:53 -0000
@@ -27,6 +27,31 @@ class PathTestCase extends DrupalWebTest
   }
 
   /**
+   * Test the path cache.
+   */
+  function testPathCache() {
+    // Create test node.
+    $node1 = $this->drupalCreateNode();
+
+    // Create alias.
+    $edit = array();
+    $edit['src'] = 'node/' . $node1->nid;
+    $edit['dst'] = $this->randomName(8);
+    $this->drupalPost('admin/build/path/add', $edit, t('Create new alias'));
+
+    // Visit the system path for the node and confirm a cache entry is
+    // created.
+    cache_clear_all('*', 'cache_path', TRUE);
+    $this->drupalGet($edit['src']);
+    $this->assertTrue(cache_get($edit['src'], 'cache_path'), t('Cache entry was created.'));
+
+    // Visit the alias for the node and confirm a cache entry is created.
+    cache_clear_all('*', 'cache_path', TRUE);
+    $this->drupalGet($edit['dst']);
+    $this->assertTrue(cache_get($edit['src'], 'cache_path'), t('Cache entry was created.'));
+  }
+
+  /**
    * Test alias functionality through the admin interfaces.
    */
   function testAdminAlias() {
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.323
diff -u -p -r1.323 system.install
--- modules/system/system.install	12 May 2009 13:43:45 -0000	1.323
+++ modules/system/system.install	16 May 2009 18:24:57 -0000
@@ -606,6 +606,8 @@ function system_schema() {
   $schema['cache_page']['description'] = 'Cache table used to store compressed pages for anonymous users, if page caching is enabled.';
   $schema['cache_menu'] = $schema['cache'];
   $schema['cache_menu']['description'] = 'Cache table for the menu system to store router information as well as generated link trees for various menu/page/user combinations.';
+  $schema['cache_path'] = $schema['cache'];
+  $schema['cache_path']['description'] = 'Cache table for path alias lookup.';
   $schema['cache_registry'] = $schema['cache'];
   $schema['cache_registry']['description'] = 'Cache table for the code registry system to remember what code files need to be loaded on any given page.';
 
@@ -3467,6 +3469,17 @@ function system_update_7023() {
 }
 
 /**
+ * Create the cache_path table.
+ */
+function system_update_7024() {
+  $ret = array();
+  $schema['cache_path'] = drupal_get_schema_unprocessed('system', 'cache');
+  $schema['cache_path']['description'] = t('Cache table used for path alias lookups.');
+  db_create_table($ret, 'cache_path', $schema['cache_path']);
+  return $ret;
+}
+
+/**
  * @} End of "defgroup updates-6.x-to-7.x"
  * The next series of updates should start at 8000.
  */
? sites/all/modules/pqp/d7.patch
