Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.951
diff -u -p -r1.951 common.inc
--- includes/common.inc	31 Jul 2009 19:56:09 -0000	1.951
+++ includes/common.inc	31 Jul 2009 21:31:07 -0000
@@ -2036,6 +2036,10 @@ function _format_date_callback(array $ma
  * alternative than url().
  */
 function url($path = NULL, array $options = array()) {
+  global $base_url;
+  static $script;
+  static $locale;
+  static $custom_url_rewrite;
   // Merge in defaults.
   $options += array(
     'fragment' => '',
@@ -2053,7 +2057,10 @@ function url($path = NULL, array $option
   }
 
   // May need language dependent rewriting if language.inc is present.
-  if (function_exists('language_url_rewrite')) {
+  if (!isset($locale)) {
+    $locale = function_exists('language_url_rewrite');
+  }
+  if ($locale) {
     language_url_rewrite($path, $options);
   }
   if ($options['fragment']) {
@@ -2079,9 +2086,6 @@ function url($path = NULL, array $option
     return $path . $options['fragment'];
   }
 
-  global $base_url;
-  $script = &drupal_static(__FUNCTION__);
-
   if (!isset($script)) {
     // On some web servers, such as IIS, we can't omit "index.php". So, we
     // generate "index.php?q=foo" instead of "?q=foo" on anything that is not
@@ -2105,16 +2109,36 @@ function url($path = NULL, array $option
     $path = drupal_get_path_alias($path, isset($options['language']) ? $options['language']->language : '');
   }
 
-  if (function_exists('custom_url_rewrite_outbound')) {
+  if (!isset($custom_url_rewrite)) {
+    $custom_url_rewrite = function_exists('custom_url_rewrite_outbound');
+  }
+
+  if ($custom_url_rewrite) {
     // Modules may alter outbound links by reference.
     custom_url_rewrite_outbound($path, $options, $original_path);
   }
 
-  $base = $options['absolute'] ? $options['base_url'] . '/' : base_path();
+  $base = $options['absolute'] ? $options['base_url'] . '/' : $GLOBALS['base_path'];
   $prefix = empty($path) ? rtrim($options['prefix'], '/') : $options['prefix'];
-  $path = drupal_encode_path($prefix . $path);
 
-  if (variable_get('clean_url', '0')) {
+  // Check clean_url directly instead of using variable_get() to avoid the
+  // overhead of an additional function call, since url() may be called
+  // hundreds of times during a request.
+  $clean_urls = !empty($GLOBALS['conf']['clean_url']);
+
+  // The following code is duplicated from drupal_encode_path() to save
+  // unnecessary function calls.
+  // @see drupal_encode_path().
+  if ($clean_urls) {
+    $path = str_replace(array('%2F', '%26', '%23', '//'),
+                        array('/', '%2526', '%2523', '/%252F'),
+                        rawurlencode($prefix . $path));
+  }
+  else {
+    $path = str_replace('%2F', '/', rawurlencode($prefix . $path));
+  }
+
+  if ($clean_urls) {
     // With Clean URLs.
     if ($options['query']) {
       return $base . $path . '?' . $options['query'] . $options['fragment'];
